dedlfix: Verschachteln von Quotes in PHP

Beitrag lesen

Hi!

Denn in der Praxis funktioniert dies bei mir leider nicht :(

"Funktioniert nicht" funktioniert nicht als Fehlerbeschreibung. Auch wenn du am Ende etwas Lauffähiges hinbekommst, krankt dein Versuch derzeit daran, dass du dich nur um die offensichtlichen Quotierzeichen kümmerst, aber andere kritische Zeichen in den Daten selbst nicht behandelst.

Schreib doch das Ganze in Einzelteilen, besonders weil du jetzt schon den Überblick verloren hast. Außerdem kannst du so die Behandlung von spezialisierten Funktionen und unter Berücksichtigung aller Zeichen vornehmen lassen.

$tiptext = 'Der erste Test Skill<br><br><img align="right" src="./icons/del.png" onclick="document.getElementById(4).style.background=none;">';

$tiptext soll der angezeigte Text sein. Der ist zwar mit HTML und Eventhandlern gespickt, doch es werden weiter keine variablen Daten eingefügt. Die Anführungszeichen beschränken sich auf ", womit es ausreicht, diesen Text im PHP-Kontext mit ' zu quotieren.
$tiptext soll als String in einem Javascript-Kontext notiert werden. Diesen Javascript-Code habe ich zunächst mit %s als Platzhalter für den $tiptext notiert. Wie du siehst, habeich wieder " zum Quotieren für die inneren Texte verwendet, und im PHP-Kontext das einfache Anführungszeichen. Unter anderen verwende ich die einfachen, wenn die Funktionalität der doppelten nicht benötigt wird - also Variableninterpretation und Sonderzeichen wie \n nicht benötigt werden.

$tip = sprintf('Tip("%s", TITLE, "Testskill_1", DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5, CLICKCLOSE, true, STICKY, true)', javascript_escape($tiptext));

sprintf() sieht das erste (und einzige) %s und nimmt das erste (und einzige) nachfolgende Argument, um es an seiner Stelle einzufügen. Das ist $tiptext, der aber von der Funktion javascript_escape() bearbeitet wurde. Leider gibt es eine solche Funktion nicht in PHP, weswegen ich eine schrieb: Abschnitt Javascript im Kontextwechsel-Artikel.

Abschließend muss nun noch $tip in den HTML-Kontext eingefügt. Dazu verwende ich printf(), das wie sprintf() mit Platzhaltern arbeitet, das Ergebnis aber (wie echo) sofort ausgibt. Um den $tip in den HTML-Kontext einzubauen, kann man PHPs Funktion htmlspecialchars() verwenden.

printf('<img src="test" OnMouseOver="%s" onmouseout="UnTip()" align="right" value="1">, htmlspecialchars($tip));

(Fast) fertig. Mehr Zeilen, etwas mehr Code aber insgesamt übersichtlicher, finde ich.

In deinem ursprünglichen Posting sind in deinem $tiptext und auch in $tip noch Variablen enthalten, die du im jetzigen Code durch feste Werte ersetzt hast. Wenn wir uns nun auch noch um diese kümmern, ändert es sich wie folgt:

$tiptext = sprintf('%s<br><br><img align="right" src="./icons/del.png" onclick="document.getElementById('%s').style.background=none;">',
  htmlspecialchars($slot_descr[$count]),
  javascript_escape($count));

Die Besonderheit ist hier, dass du einmal einen Text in einen HTML-Kontext einfügst, und den zweiten in einen Javascript-Kontext, deswegen die beiden verschiedenen Behandlungen.

Wenn $count definitiv eine Zahl ist - beispielsweise weil sie das Ergebnis der Funktion count() ist - dann benötigt sie im Prinzip keine Behandlung. Wenn es nicht sicher ist, könntest du mit intval() sicherstellen, dass ein Zahlenwert draus wird. Andererseits müssen ID-Werte im HTML-Umfeld mit einem Buchstaben (A-Za-z) beginnen - eigentlich dürftest du keine reine Zahl an der Stelle haben. Deswegen behandle ich den Wert wie einen String - und darum auch die quotierenden ' um das zweite %s. (Den onclick-Inhalt in eine weitere Variable auszulagern spar ich mir jetzt mal - einmal ' ist noch recht übersichtlich.)

Angepasst werden muss auch $tip:

$tip = sprintf('Tip("%s", TITLE, "%s", DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5, CLICKCLOSE, true, STICKY, true)',  
  javascript_escape($tiptext),  
  javascript_escape($slot_name[$count]));

Lo!