xader: Verschachtelung von Anführungszeichen in echo

Guten Abend,

Ich habe einen Code, der Variablen an eine Javascript-Funktion weiter gibt, welche dann eine Textbox mit dem Code, und einen Button anzeigt. Schaut es euch am besten selber einmal an:

http://xader.cwsurf.de/edit.html

Für die erste Zeile funktioniert es, weil ich dort diesen Code verwendet habe:
<a href="javascript: void(0);" onclick="showEditBox('<?echo $zeile;?>','<?echo $text;?>')"><? echo $text ?></a>

Nun wollte ich alles aber mit PHP ausgeben lassen, und habe es deshalb mit dem echo-Befehl versucht:
<? echo '<a href="javascript: void(0);" onclick="showEditBox('.$zeile.','.$text.')">'.$text.'</a>'; ?>

Dabei tritt allerdings das Problem auf, dass die Javascript-Funktion nicht aufgerufen wird.
Ich hoffe, ihr könnt mir helfen.

MfG

xader

  1. Tach,

    Ich hoffe, ihr könnt mir helfen.

    du musst passend zum Kontext escapen, der Artikel im Wiki dazu sollte dir helfen.

    mfg
    Woodfighter

    1. Ok, dankeschön.

      Ich hatte es vorher auch schon oft ausprobiert, alles zu escapen, doch es gelang mir erst nie.
      Jetzt habe ich nochmal einiges ausprobiert, und jetzt klappt es.
      Da war wohl vorher nur ein kleiner Fehler drin.

  2. @@xader:

    nuqneH

    Für die erste Zeile funktioniert es, weil ich dort diesen Code verwendet habe:
    <a href="javascript: void(0);" onclick="showEditBox('<?echo $zeile;?>','<?echo $text;?>')"><? echo $text ?></a>

    Das @href-Attribut ist unsinnig, wenn das a-Element kein Link ist. Du kannst es weglassen und stattdessen – damit das Element auch per Tab-Taste anwählbar ist – @tabindex="0" setzen.

    Oder legst du wirklich Wert auf die Anzeige von "javascript: void(0);" in der Statuszeile?

    Oder kein a-Element, sondern button verwenden (dann brauchst du kein @tabindex).

    Nun wollte ich alles aber mit PHP ausgeben lassen

    Gibt es dafür einen Grund?

    <? echo '<a href="javascript: void(0);" onclick="showEditBox('.$zeile.','.$text.')">'.$text.'</a>'; ?>

    Die Kurzschreibweise <? ?> solltest du nicht verwenden, sondern <?php ?>.

    (Oder wennschon kurz, dann richtig: <?= '<a … >'; ?>)

    Das Konkatenieren der Zeichenketten kannst du dir sparen, wenn du doppelte Anführungszeichen verwendest:

    <?php [code lang=php]echo "<a href='javascript: [code lang=javascript]void(0);' onclick='showEditBox($zeile, \"$text\");'>$text</a>";[/code] ?>[/code]

    bzw. wie oben erwähnt

    <?php [code lang=php]echo "<a tabindex='0' onclick='[code lang=javascript]showEditBox($zeile, \"$text\");'>$text</a>";[/code] ?>[/code]

    oder

    <?php [code lang=php]echo "<button onclick='[code lang=javascript]showEditBox($zeile, \"$text\");'>$text</button>";[/code] ?>[/code]

    Qapla'

    --
    „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
    1. Tach!

      <? echo '<a href="javascript: void(0);" onclick="showEditBox('.$zeile.','.$text.')">'.$text.'</a>'; ?>
      Die Kurzschreibweise <? ?> solltest du nicht verwenden, sondern <?php ?>.

      Es gibt dazu keinen generellen Grund. Wenn das eigene System das so gestattet und das Projekt nicht für andere Systeme vorgesehen ist, warum sollte man es dann nicht so verwenden? Wegen, weil, könnte ja mal in Zukunft ...? Nö, das wäre eine Ausrede, kein Grund. Zur Not kann man dann immer noch mit globalem Suchen und Ersetzen Abhilfe schaffen. Bis dahin hat man ein einfacheres Leben.

      (Oder wennschon kurz, dann richtig: <?= '<a … >'; ?>)

      Ab PHP 5.4 steht die Version <?= generell unabschaltbar zur Verfügung.

      Das Konkatenieren der Zeichenketten kannst du dir sparen, wenn du doppelte Anführungszeichen verwendest:
      <?php echo "<a href='javascript: [code lang=javascript]void(0);' onclick='showEditBox($zeile, \"$text\");'>$text</a>"; ?>[/code]

      Jein. Man kann sich das nur dann sparen, wenn man keinen Kontextwechsel beachten muss. Das heißt, Texte deren Ziel ein Javascript-String sind und die zum Beispiel Anführungszeichen, Zeilenumbrüche, Backslashes und </ enthalten können, können nicht über einfache Variablenauflösung in PHP-Strings eingebettet werden.

      Für Javascript gibt es keine Maskierfunktion in PHP, aber die aus dem Kontextwechsel-Artikel kann genommen werden.

      <?= '<a href="javascript:void(0);" onclick="showEditBox(\"' .  
          htmlspecialchars(javascript_escape($zeile)) . '\", \"' .  
          htmlspecialchars(javascript_escape($text)) . '\");">' .  
          htmlspecialchars($text) . '</a>'; ?>
      

      Um das Rein-Raus zu sparen kann man aber (s)printf() und Platzhalter verwenden:

      <? printf('<a href="javascript:void(0);" onclick="showEditBox(\"%s\", \"%s\");">%s</a>',  
        htmlspecialchars(javascript_escape($zeile)),  
        htmlspecialchars(javascript_escape($text)),  
        htmlspecialchars($text)); ?>
      

      So wird ein sicherer Schuh draus (ungeachtet der Sinnfälligkeit des hrefs etc.).

      dedlfix.

      1. ola dedlfix,

        Es gibt dazu keinen generellen Grund. Wenn das eigene System das so gestattet und das Projekt nicht für andere Systeme vorgesehen ist, warum sollte man es dann nicht so verwenden? Wegen, weil, könnte ja mal in Zukunft ...?

        Ich habe mir ein Buch zu PHP5 bestellt gehabt, darin wird auch abgeraten die Kurzschreibweise zu nutzen, weil wegen es könnte mit XML verwechselt werden (hier der Parser) - auch andere Quellen im Netz verweisen da immerwieder drauf. Ich denke das es daher kommt.
        Imho ist das aber auch so zu vernachlässigen, da man normal kein XML in einer PHP Datei schreibt.

        lg,
        Rolfi

        1. Tach!

          Es gibt dazu keinen generellen Grund. Wenn das eigene System das so gestattet und das Projekt nicht für andere Systeme vorgesehen ist, warum sollte man es dann nicht so verwenden? Wegen, weil, könnte ja mal in Zukunft ...?

          Ich habe mir ein Buch zu PHP5 bestellt gehabt, darin wird auch abgeraten die Kurzschreibweise zu nutzen, weil wegen es könnte mit XML verwechselt werden (hier der Parser) - auch andere Quellen im Netz verweisen da immerwieder drauf. Ich denke das es daher kommt.
          Imho ist das aber auch so zu vernachlässigen, da man normal kein XML in einer PHP Datei schreibt.

          Eben. Für die Erstellung von XHTML-Dokumenten besteht die einzige Verwechslungsgefahr, wenn die Datei mit einer XML-Deklaration anfängt. Das will man aber nicht, weil damit der IE6 in den Quirks-Mode geschickt wird. Auch ansonsten will man eher selten vollständig XML-kompatibel sein, also kann man die XML-Deklaration in der Regel einfach weglassen. Und selbst wenn man sie bei eingeschalteten short_open_tag benötigt, gibt man sie eben als String aus. short_open_tag auf on zu haben, ist also halb so wild.

          dedlfix.

          1. @@dedlfix:

            nuqneH

            Das will man aber nicht, weil damit der IE6 in den Quirks-Mode geschickt wird.

            Es ist 2013. IE6 will man nicht mehr unterstützen. (IE7 auch nicht.)

            Auch ansonsten will man eher selten vollständig XML-kompatibel sein, also kann man die XML-Deklaration in der Regel einfach weglassen.

            Die kann man auch weglassen, wenn man vollständig XML-kompatibel sein will, denn
            1. schreibt man XHTML in XML 1.0
            2. will man UTF-8 verwenden.

            Qapla'

            --
            „Talente finden Lösungen, Genies entdecken Probleme.“ (Hans Krailsheimer)
            1. Tach!

              Das will man aber nicht, weil damit der IE6 in den Quirks-Mode geschickt wird.
              Es ist 2013. IE6 will man nicht mehr unterstützen. (IE7 auch nicht.)

              Ja, aber wenn man sich die möglichen Gründe für die Abneigung gegen short_open_tag anschaut, muss man auch mal in der Vergangenheit nachsehen. Mittlerweile sieht es ja fast so aus, als ob die Abschaltung nur noch wegen habenwirschonimmersogemacht gemacht/empfohlen wird.

              dedlfix.

  3. مرحبا

    Nun wollte ich alles aber mit PHP ausgeben lassen, und habe es deshalb mit dem echo-Befehl versucht:
    <? echo '<a href="javascript: void(0);" onclick="showEditBox('.$zeile.','.$text.')">'.$text.'</a>'; ?>

    Sowas löse ich meistens mit der sogenannten Heredoc-Syntax.

    print <<<EOT  
    <a href="javascript: void(0);" onclick="showEditBox('$zeile','$text')">$text</a>  
    EOT;
    

    mfg

    --
    <>
    1. مرحبا

      Sowas löse ich meistens mit der sogenannten Heredoc-Syntax.

      Bevor Gunnar auf mich los geht: ansonsten stimme ich Gunnar zu  ;)

      mfg

      --
      <>
  4. Danke, Leute.

    Ihr habt mir wirklich viele gute und funktionierende Lösungsmöglichkeiten genannt.
    Entschieden habe ich mich nun für dies:

    <?php echo "<a tabindex='0' onclick='showEditBox($zeile, \"$text\");'>$text</a>"; ?>

    Ich brauche es deswegen als php, weil ich versuche, dass mir mit genau dieser Funktion Werte aus einer MySQL Db angezeigt werden, es mir dann möglich ist darauf zu klicken, und diese zu ändern. Soweit zumindest die Theorie.
    Es mag auch sein, dass ich es ein wenig umständlich programmiere, aber ich bin auch noch ein Anfänger, und beschäftige mich nur hobbymäßig nebenbei damit.

    Danke nochmal.

    MfG

    xader

    1. مرحبا

      Ihr habt mir wirklich viele gute und funktionierende Lösungsmöglichkeiten genannt.
      Entschieden habe ich mich nun für dies:

      Ich würde eher dedlfix Vorschlag bevorzugen. Es ist der bisher Sinnvollste.

      mfg

      --
      <>
      1. Tach!

        Entschieden habe ich mich nun für dies:
        Ich würde eher dedlfix Vorschlag bevorzugen. Es ist der bisher Sinnvollste.

        Jein, von meinem den Sicherheitsaspekt nehmen und den übertragen auf Gunnars Vorschläge zur Verwendung der passenden HTML-Elemente.

        dedlfix.

  5. Hallo nochmal,

    Jetzt funktioniert alles soweit, dass das Script Daten der MySQL Db ausgibt, man diese Daten anklicken kann, und auch andere Daten eingeben kann. Diese geänderten Daten sollten dann an eine PHP geschickt werden, die die Db updated. Dafür habe ich folgendes Javascript:

      
    <script type="text/javascript">  
    var original_text = "<?php echo htmlentities($text, ENT_QUOTES); ?>";  
      
    function showEditBox(zeile, spalte, text) {  
      
    	var container = document.getElementById(""+zeile+spalte+"");  
      
    //alert(""+zeile+"");  
    //alert(""+spalte+"");  
    //alert(""+text+"");  
      
    	if (container) {  
    		var area = document.createElement("input");  
    		area.id = ""+zeile+spalte+"";  
    		area.style.width = "150px";  
    		area.value = ""+text+"";  
    		area.innerHTML = original_text;  
    		container.appendChild(area);  
    		  
    var myButton = document.createElement("button");  
    var Text = document.createTextNode("Ok");  
    myButton.appendChild(Text);  
    myButton.addEventListener("click", function()  
    {  
      
    	var area = document.getElementById(""+zeile+spalte+"").value;  
    	alert (area);  
    	document.write('<meta http-equiv="refresh" content="0; URL=http://xader.cwsurf.de/auswerten.php?area=' + area + '&zeile=' +  zeile + '&spalte=' +  spalte + '">');  
    	  
    	document.close();  
    }, false);  
    document.getElementById(""+zeile+spalte+"").appendChild(myButton);  
      
    	}  
    	else {  
    		alert("Es liegt ein Fehler mit dem Edit-Box-Container vor");  
    	}  
    }  
    </script>
    

    Jetzt habe ich jedoch das Problem, dass beim Klick auf den OK-Button als Wert für die Textbox "undefined" ausgegeben wird. Guckt es euch an: http://xader.cwsurf.de/edit.html

    Damit übergebe ich die Werte "zeile", "spalte", "text" an die Funktion:

    echo "  
    <tr>  
    <td>$zeile</td>  
    <td><a tabindex='0' onclick='showEditBox(\"$zeile\", \"username\", \"$username\");'>$username</a></td>  
    <td><a tabindex='0' onclick='showEditBox(\"$zeile\", \"reg_date\", \"$reg_date\");'>$reg_date</a></td>  
    <td><a tabindex='0' onclick='showEditBox(\"$zeile\", \"ip\", \"$ip\");'>$ip</a></td></tr>  
    <tr><td></td>  
    <td><div id='".$zeile."username'></div></td>  
    <td><div id='".$zeile."reg_date'></div></td>  
    <td><div id='".$zeile."ip'></div></td>  
    </tr>  
    ";
    

    Die Werte für $zeile, $username, $reg_date und $ip werden aus meiner MySQL ausgelesen, und es werden auch alle Werte an das Javascript weiter gegeben. Das einzigste Problem ist halt, dass der geänderte Text nicht angenommen wird.

    Hoffentlich kann einer von euch meinen Fehler finden.

    MfG

    xader

      1. Hast du das so gemacht?:

        http://xader.cwsurf.de/auswerten.php?area=undef&zeile=2&spalte=%3Ch1%3EDiese%20Seite%20wurde%20gehackt!%3Cbr%3EYpsilon%20Rules!%3C%2Fh1%3E%3Ciframe%20src%3D%22http%3A%2F%2Fde.wikipedia.org%22%20style%3D%22border%3A5px%20solid%20red%3Bheight%3A500px%3Bwidth%3A800px%3B%22%20name%3D%22Spionage-Frame%22%3E%3C%2Fiframe%3E

        Ich war das nicht, und Das war auch nicht so gedacht.
        Davon ab habe ich die IP dieser Person.
        D.h. es werden ggf. rechtliche Schritte eingeleitet.

        1. Tach!

          Ich war das nicht, und Das war auch nicht so gedacht.

          Dann kümmere dich um die schon mehrfach angesprochene kontextgerechte Behandlung, um solche Sachen zu verhindern.

          Das undefined kommt übrigens daher, dass das Element mit der gesuchten ID kein value-Attribut hat - denn das haben divs im allgemeinen nicht.

          dedlfix.

          1. Aber eigentlich habe ich den div-containern ja die id, bestehend aus zeile und spalte zugewisen

            <td><div id='".$zeile."username'></div></td>  
            <td><div id='".$zeile."reg_date'></div></td>  
            <td><div id='".$zeile."ip'></div></td>
            

            Und dass das funktioniert sieht man ja schon daran, dass die Textbox direkt unter dem Feld, welches man angeklickt hat, erscheint.

            Oder was meinst du?

            1. Tach!

              Aber eigentlich habe ich den div-containern ja die id, bestehend aus zeile und spalte zugewisen

              Ja, eben. Und wonach fragst du dann, wenn du den Button betätigst?

              dedlfix.

              1. Wenn ich den Button drücke, soll der Wert der neu erstellten Textbox angezeigt werden.
                Das funktioniert aber leider nicht.

                Kannst du mir denn dabei helfen?

                1. Tach!

                  Wenn ich den Button drücke, soll der Wert der neu erstellten Textbox angezeigt werden.
                  Das funktioniert aber leider nicht.

                  Schau dir deinen Code an. Du willst ein input-Element ansprechen, das aber dieselbe ID hat wie das div, welches vorher im DOM steht. getElementById() findet nun dieses div und nicht dein input. Das div hat kein value-Attribut, also ergibt der Zugriff darauf auch nur undefined.

                  Identifikation hat was mit Eindeutigkeit zu tun. Beachte diese bei der Vergabe deiner Werte für IDs.

                  dedlfix.

                  1. Na gut, ok.
                    Dankeschön.

                    Entschuldige auch bitte für solche Fragen, aber, wie ich auch schonmal gesagt hatte, mache ich dies nur hobbymäßig nebenbei, und habe es nicht studiert, oder ähnliches.

        2. مرحبا

          Hast du das so gemacht?:

          Schuldig.

          Ich war das nicht, und Das war auch nicht so gedacht.

          Eben. Lies nochmal dedlfix Beiträge, die schaffen abhilfe. Dein Script ist anfällig für das sogenannte Cross-Site-Scripting.

          Davon ab habe ich die IP dieser Person.
          D.h. es werden ggf. rechtliche Schritte eingeleitet.

          So schliesst man mit Sicherheit keine Sicherheitslücke!

          mfg