xylon: Verschachteln von Quotes in PHP

Hi,
ich habe folgenden PHP Code:

echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById($count).style.background=none;\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";

Das ganze funktioniert auch bis auf das onclick, welches ich als HTML-Code an die Funktion Tip() übergeben will.
Um dieses onclick zum Funktionieren zu bringen, müsste ich das none in anführungszeichen setzen.... Da ich jedoch bereits ", ", ' und ' verwendet habe, kann ich hier keine der eben genannten Quotes verwenden.

Hat hierzu jemand eine passende Lösung parat?

MfG
xylon

  1. Hi,
    ich habe folgenden PHP Code:

    echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById($count).style.background=none;\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";

    Ähm schau dir mal das an was du da fabriziert hast, da stimmt aber sowieso was am Syntax nicht.

    lg

    1. Was stimmt da am Syntax nicht?

      Es funktioniert eigendlich einwandfrei, bis eben auf das onclick event, welches ich als HTML-Code an die Funktion Tip() übergeben will!

      Wenn ich beispielsweise einfach ein onclick'alert(123)' verwede, klappt auch das!

      1. Was stimmt da am Syntax nicht?

        Es funktioniert eigendlich einwandfrei, bis eben auf das onclick event, welches ich als HTML-Code an die Funktion Tip() übergeben will!

        Wenn ich beispielsweise einfach ein onclick'alert(123)' verwede, klappt auch das!

        Zitat: "OnMouseOver="Tip('$slot_descr[$count]<br><br><img align='right'
                                            ^^^^^^^^^^^^^^^^^

        lg

        1. Was stimmt da am Syntax nicht?

          Es funktioniert eigendlich einwandfrei, bis eben auf das onclick event, welches ich als HTML-Code an die Funktion Tip() übergeben will!

          Wenn ich beispielsweise einfach ein onclick'alert(123)' verwede, klappt auch das!

          Zitat: "OnMouseOver="Tip('$slot_descr[$count]<br><br><img align='right'
                                              ^^^^^^^^^^^^^^^^^

          Ahso vergiss es .. ich hab da übersehen das du dass mit verschachteln gemeint hast.

          lg

          1. Ahso vergiss es .. ich hab da übersehen das du dass mit verschachteln gemeint hast.

            Ah ok, dachte schon ich bin ezu blöd dafür was du meinst ^^
            der HTML-Code soll im 1. Parameter an die Funktion Tip() übergeben werden!

      2. Hi xylon.

        Was stimmt da am Syntax nicht?

        Das Geschlecht.

        ;-)

        Viele Gruesse,
        der Bademeister

  2. Hi,
    ich habe folgenden PHP Code:

    echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById($count).style.background=none;\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";

    Das ganze funktioniert auch bis auf das onclick, welches ich als HTML-Code an die Funktion Tip() übergeben will.
    Um dieses onclick zum Funktionieren zu bringen, müsste ich das none in anführungszeichen setzen.... Da ich jedoch bereits ", ", ' und ' verwendet habe, kann ich hier keine der eben genannten Quotes verwenden.

    Wieso das?
    Dir scheint noch nicht ganz klar zu sein, wie Quotierung in PHP funktioniert.

    Ein String mit einfachen Hochkommata ('...') stellt alles _genau_ so dar, wie es angegeben wird. Ohne Ausnahme. Und zwar vom ersten Hochkommata bis zum Zweiten.

    Ein String mit doppelten Hochkommata ("...") interpretiert hingegen zusätzlich auch noch Variablen (oder vielleicht auch noch mehr). Auch hier geht der String vom ersten bis zum nächsten Hochkomma. Möchte man nun innerhalb dieses Strings selbst ein Hochkomma benutzen, escaped man dieses mit einem Backslash ("). Alles andere muss _nicht_ quotiert werden. Auch einfache Hochkommata müssen _nicht_ quotiert werden.
    Du kannst also die ganzen Backslashes vor deinen ' wieder löschen.

    1. Mahlzeit Wouzhuo,

      Dir scheint noch nicht ganz klar zu sein, wie Quotierung in PHP funktioniert.

      Dir hingegen scheint nicht klar zu sein, wie Quotierung in Javascript funktioniert.

      Du kannst also die ganzen Backslashes vor deinen ' wieder löschen.

      Nein, kann er nicht. Und zwar weil Teil des Attributwerts des HTML-Elements, das durch den PHP-String dargestellt wird, der Aufruf einer Javascript-Funktion ist, der als Parameter ein String übergeben wird, der wiederum Hochkommata enthält. Und diese *müssen* in dem Fall maskiert werden.

      Ich drösel das mal auf:

      PHP:  echo "

      HTML: OnMouseOver="

      JS:   Tip('$slot_descr[$count]<br><br><img align='right' src='./icons/del.png' onclick='document.getElementById($count).style.background=none;'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)

      HTML: " onmouseout="

      JS:   UnTip()

      HTML: "

      PHP:  ";

      Der problematische Teil hierbei ist der Inhalt des ersten HTML-Attributs, also der Aufruf der Javascript-Funktion "Tip()".

      Da es sich also um ein Client-seitiges Problem handelt, sollte xylon mal zeigen, welcher Code letztendlich im Browser ankommt.

      MfG,
      EKKi

      --
      sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
      1. Hallo EKKi,

        Da es sich also um ein Client-seitiges Problem handelt, sollte xylon mal zeigen, welcher Code letztendlich im Browser ankommt.

        Clientseitig siet der Quellcode dann wie folgt aus:
        <img src="test" OnMouseOver="Tip('Der erste Test Skill<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById(4).style.background=none;\'>',TITLE, 'Testskill_1', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)" onmouseout="UnTip()" align="right" value="1">

        »»Ein inneres " wird als \ und " gesehen und als \ und " notiert

        Wenn ich die erläuterung von Lo! richtig verstanden habe,
        kann ich somit innerhalb eines " ein " verwenden, und innerhalb eines " ein \" (ein zusätzliches \ um das \ zu Escapen und ein \ um das " zu Escapen) verwenden. Habe ich das so richtig verstanden?

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

        Gruß
        Xylon

        1. Mahlzeit xylon,

          Da es sich also um ein Client-seitiges Problem handelt, sollte xylon mal zeigen, welcher Code letztendlich im Browser ankommt.

          Clientseitig siet der Quellcode dann wie folgt aus:
          <img src="test" OnMouseOver="Tip('Der erste Test Skill<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById(4).style.background=none;\'>',TITLE, 'Testskill_1', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)" onmouseout="UnTip()" align="right" value="1">

          Dabei fallen mir spontan einige Dinge auf - ob sie eine direkte Auswirkung auf Dein Problem haben, kann ich nicht beurteilen, da Du noch keine konkrete Fehlermeldung genannt hast:

          1.) Eine ID darf nicht nur numerisch sein. Insofern kann "document.getElementById(4)" nur bedeuten, dass Dein HTML-Code schon nicht valide ist. Überprüfe das und korrigiere es ggf.

          2.) Was befindet sich jeweils in den Javascript-Variablen TITLE, DELAY, FOLLOWMOUSE, PADDING, CLICKCLOSE und STICKY? Sinnvolle Werte?

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

          Tut mir leid, aber "funktioniert nicht" funktioniert leider nicht.

          MfG,
          EKKi

          --
          sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
          1. Hi,

            Habe Das Problem nun vollständig gelöst.
            Danke für die info mit der ID! Habe dies nun abgeändert :)

            Gruß
            Xylon

        2. 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!

  3. Hi!

    echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById($count).style.background=none;\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";
    Um dieses onclick zum Funktionieren zu bringen, müsste ich das none in anführungszeichen setzen.... Da ich jedoch bereits ", ", ' und ' verwendet habe, kann ich hier keine der eben genannten Quotes verwenden.
    Hat hierzu jemand eine passende Lösung parat?

    Löse solche Knoten von innen nach außen auf. Zunächst möchtest du einen Wert in ein bestimmtes System einfügen. Dazu musst du dessen Regeln kennen, wie welche Zeichen notiert werden müssen, damit sie am Ende als ein bestimmte Zeichen interpretiert werden und nicht vielleicht als Steuerzeichen oder andere mit besonderer Bedeutung. Dieser Vorgang nennt sich Maskieren (oder Escapen). Wenn du diesen so behandelten Wert in einen Code-Kontext einfügen möchtest, werden er im Allgemeinen mit Begrenzungszeichen eingefasst - Quotieren genannt. Nun hast du ein Gebilde aus Code und (hoffentlich) korrekt notierten Daten. Dieses Gebilde möchtest du in einen weiteren Kontext einfügen. Dabei gehst du genauso vor, betrachtest das Gebilde aber rein als Daten. Die Zeichen, die im inneren Kontext eine Sonderbedeutung haben, interessieren nicht als solche. Vielmehr wird jedes Zeichen einzeln betrachtet und gemäß den Regeln den neuen Kontexts behandelt. Ein inneres " wird als \ und " gesehen und als \ und " notiert, wenn die Regeln des äußeren Kontexts einen vorangestellten Backslash vorsehen.

    Dass du mit ' und " zwei verschiedene Quotierungen zur Verfügung hast, die unmaskiert in zwei Systemen verschachteln kannst, steht auf einem anderen Blatt.

    Eine weitere Möglichkeit, Daten zu schachteln, und dies noch dazu übersichtlicher als ein großes Gebilde, bietet die Funktion sprintf(). Notiere zunächst den feststehenden Teil und einen Platzhalter %s (gegebenenfalls mit Quotierzeichen drumrum. Die Werte werden dann anschließend mit der passenden Behandlungsfunktion angegeben. Beispielsweise so:

    $html = sprintf('<input type="text" name="foo" value="%s">', htmlspecialchars($foo));

    Auch das kann man schachteln. $html wird dann in dem anderen Kontext ähnlich behandelt wie $foo im eben gezeigten Beispiel.

    Lo!

    1. Danke für die sehr Ausfürhliche erläuterung!!

  4. Hallo xylon,

    echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById($count).style.background=none;\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";

    hopala...

    Gliedere document.getElementById($count).style.background=none; in eine eigene Javascriptfunktion aus:

    function problem(element){  
       document.getElementById(element).style.background="none";  
    }
    

    Somit würde die PHP-Ausgabe so aussehen:

    echo "OnMouseOver=\"Tip('$slot_descr[$count]<br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'problem($count)\'>',TITLE, '$slot_name[$count]', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)\" onmouseout=\"UnTip()\"";

    Ansonsten reicht auch schlichter Standard:

    <element OnMouseOver="Tip('<?php echo $slot_descr[$count];?><br><br><img align=\'right\' src=\'./icons/del.png\' onclick=\'document.getElementById(<?php echo $count;?>).style.background=none;\'>',TITLE, '<?php echo $slot_name[$count];?>', DELAY, 1000, FOLLOWMOUSE, false, PADDING, 5,CLICKCLOSE,true,STICKY, true)" onmouseout="UnTip()";></element>[/code]

    Gruß aus Berlin!
    eddi

    1. Perfekt!
      Danke für die schnellen Antworten!

      Gruß
      xylon