Sub: _POST Array mit htmlspecialchars und ENT_QUOTES ausgeben

Hallo an alle Mitglieder/innen dieses Forums,

ich habe ein Problem bei der Ausgabe des $_POST Arrays mit htmlspecialchars und ENT_QUOTES!

Beispiel:

Ich gebe in eine textarea auf seite1.php folgendes ein:

' " & < >

Dieser Wert wird auf die seite2.php gesendet und mittels nachfolgenden Code ausgegeben:

<?php
echo "<pre>\r\n";
echo htmlspecialchars(print_r($_POST, ENT_QUOTES));
echo "</pre>\r\n";
?>

Im Html Quelltext steht jetzt:

<pre>
Array
(
 [textarea] =&gt; ' &quot; &amp; &lt; &gt;
)
</pre>

Müsste es nicht eigentlich so ausgegeben werden:

<pre>
Array
(
[textarea] =&gt; &#039; &quot; &amp; &lt; &gt;
)
</pre>

Warum wird das einfache Anführungszeichen nicht Umgewandelt?
Ist das beim POST Array normal oder mache ich etwas falsch?

Freue mich über jede Hilfestellung, Danke!

Gruß,

Sub

  1. Ist das beim POST Array normal oder mache ich etwas falsch?

    Du machst die Klammern falsch und hast das Error-Reporting aus, ansonsten würde dir gesagt werden, dass ENT_QUOTES für print_r kein zulässiger Wert für den zweiten Parameter ist.

    1. Hallo suit,

      vielen Dank für Deine Hilfe.

      Also Error-Reporting ist an, siehe:

      <?php
      error_reporting(E_ALL);
      ini_set('display_errors', TRUE);
      ?>

      Es gibt aber keine Fehlermeldung heraus!

      Gruß,

      Sub

      1. Hallo dedlfix, Matze, suit, Sven Rautenberg und Tom,

        hiermit bedanke ich mich verspätet für eure große Anteilnahme und Hilfe zu meiner Fragestellung!!!

        Viele Grüße,

        Sub

    2. Hello,

      Ist das beim POST Array normal oder mache ich etwas falsch?

      Du machst die Klammern falsch und hast das Error-Reporting aus, ansonsten würde dir gesagt werden, dass ENT_QUOTES für print_r kein zulässiger Wert für den zweiten Parameter ist.

      Ist das so? ENT_QUOTES ist größer 0 und müsste daher true ergeben als Funktionsargument an dieser Stelle und das wäre dann zulässig.

      Ich gestehe, dass ich mir die Reaktion des Parsers jetzt nicht angesehen habe, sondern nur aus meinem Verständnis heraus argumentiere...

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. Hi!

        Du machst die Klammern falsch und hast das Error-Reporting aus, ansonsten würde dir gesagt werden, dass ENT_QUOTES für print_r kein zulässiger Wert für den zweiten Parameter ist.
        Ist das so? ENT_QUOTES ist größer 0 und müsste daher true ergeben als Funktionsargument an dieser Stelle und das wäre dann zulässig.

        Ganz richtig und suit liegt falsch. Syntaktisch gesehen ist alles in bester Ordnung. ENT_QUOTES ist int(3) und ist damit als zweites Argument für print_r() nichts anderes als wenn man 1 statt true übergibt.

        Lo!

        1. Ganz richtig und suit liegt falsch. Syntaktisch gesehen ist alles in bester Ordnung. ENT_QUOTES ist int(3) und ist damit als zweites Argument für print_r() nichts anderes als wenn man 1 statt true übergibt.

          Das habe ich bereits festgestellt, ja.

          In der Doku ist folgendes Vermerkt:

          mixed print_r ( mixed $expression [, bool $return = false ] )

          Ich hatte eben nicht erwartet, dass z.B. auch Ganzzahlen oder gar irgendwelche imho unsinnigen Dinge nach true gecastet werden.

          1. Hi!

            Ich hatte eben nicht erwartet, dass z.B. auch Ganzzahlen oder gar irgendwelche imho unsinnigen Dinge nach true gecastet werden.

            Das ist eine der Haupteigenschaften von PHP, dass es in der Regel stillschweigend automatisch alles in jede Richtung castet. Das stammt auch aus Zeiten, als es noch kein dediziertes true und false gab und man stattdessen 1 und 0 verwendete. Dieser Mechanismus macht auch vor Arrays und Objekten nicht halt. Man kann dann recht einfach

            if ($array)

            schreiben und muss das nicht ausführlich als

            if (count($array) > 0)

            notieren.

            Lo!

            1. Das ist eine der Haupteigenschaften von PHP, dass es in der Regel stillschweigend automatisch alles in jede Richtung castet.

              Dass da viel automatisch gecastet wird, ist mir schon lange klar - nur so einen Fall auszuprobieren oder diesbezüglich nachzuschlagen kam mir bisher nicht in den Sinn.

              Das stammt auch aus Zeiten, als es noch kein dediziertes true und false gab und man stattdessen 1 und 0 verwendete.

              Das ist einleuchtend, meinetwegen auch noch 0 und -1, aber dass die nicht definierte Konstante "FAIL" z.B. auch nach true validiert ist etwas komisch - ich hätte erwartet, dass nicht gesetzte Variablen oder nicht definierte Konstanten nach false gecastet werden.

              Dieser Mechanismus macht auch vor Arrays und Objekten nicht halt. Man kann dann recht einfach

              Auch das ist mir klar.

              1. Hi!

                Das stammt auch aus Zeiten, als es noch kein dediziertes true und false gab und man stattdessen 1 und 0 verwendete.

                Das ist einleuchtend, meinetwegen auch noch 0 und -1, aber dass die nicht definierte Konstante "FAIL" z.B. auch nach true validiert ist etwas komisch - ich hätte erwartet, dass nicht gesetzte Variablen oder nicht definierte Konstanten nach false gecastet werden.

                Schalte das error_reporting auf E_ALL, dann wird dir durch die nun angezeigten Notice-Meldungen bestimmt einiges klarer. Nicht vorhandene Variablen ergeben im boolschen Kontext false und die Konstanten ergeben true, weil bei denen noch ein anderer Mechanismus mit reinspielt.

                Den schlechten Ruf unter erfahreneren Programmierern hat es sich durch seine Anfängerfreundlichkeit erarbeitet, weil es eben viel und manches recht ungewöhnlich automatisiert. Es gibt aber für alles eine Erklärung, egal ob man die nun gut findet oder nicht. Lesezugriffe auf nicht vorhandene Variablen ergeben null als Resultat, und das entspricht false. Dass nicht vorhandene Konstanten nach true evaluieren, liegt daran, dass PHP davon ausgeht, man wollte eigentlich einen String schreiben, also wird der Konstantenname als String angesehen und der evaluiert stets nach true, weil ein Konstantenname kein Leerstring oder 0 sein kann und false und null schon als Schlüsselwörter definiert sind. Vergleiche PHP type comparison table erste Tabelle, erste und letzte Spalte. Diesen String-Mechanismus braucht man um Anfängern solche Fehler wie $foo[bar] zu verzeihen, das eigentlich $foo['bar'] beziehungsweise $foo["bar"] hätte geschrieben werden müssen. (Es sei denn man ist in einem ""-String, da muss man die ''/"" weglassen "bla $foo[bar] fasel" oder extra noch mit {} klammern "bla {$foo['bar']} fasel" jedoch nicht beides zugleich, also mit {} aber ohne '' wie in "bla {$foo[bar]} fasel". Hier schlägt dann wieder der Konstantenmechanismus zu. Variable parsing)

                Lo!

  2. Moin!

    <?php
    echo "<pre>\r\n";
    echo htmlspecialchars(print_r($_POST, ENT_QUOTES));
    echo "</pre>\r\n";
    ?>

    print_r ist genauso eine Funktion wie echo.

    Das bedeutet: print_r hat keinen wirklichen Rückgabewert, den du in htmlspecialchars() reintun könntest, der dann escaped wird.

    Ausgeführt würde also sowas:

    <?php
    echo "<pre>\r\n";
    print_r($_POST);
    echo htmlspecialchars('');
    echo "</pre>\r\n";
    ?>

    Ok, jetzt hast du den Parameter ENT_QUOTES fälschlich in print_r reingetan, anstatt ihn in htmlspecialchars() zu verwenden. der zweite Parameter von print_r sorgt dafür, dass diese Funktion eben doch keine direkte Ausgabe macht, wenn dieser Parameter "true" ergibt. ENT_QUOTES ist eine Konstante, die zu "true" evaluiert.

    Deshalb kriegst du als Resultat dann eher sowas:

    <?php
    echo "<pre>\r\n";
    echo htmlspecialchars('...der String aus print_r');
    echo "</pre>\r\n";
    ?>

    Hier ist von der Wirkung von ENT_QUOTES aber eben nichts zu sehen.

    Ist das beim POST Array normal oder mache ich etwas falsch?

    Du machst was falsch. Deine beiden Fehler heben sich aber so gegenseitig gegeneinander auf, dass am Ende etwas halbrichtiges rauskommt, und kein kompletter Fail.

    - Sven Rautenberg

    1. Du machst was falsch. Deine beiden Fehler heben sich aber so gegenseitig gegeneinander auf, dass am Ende etwas halbrichtiges rauskommt,

      var_dump(ENT_QUOTES); liefert int(3)

      (3 == true) trifft aber zu - was ich jetzt nicht erwartet habe.

      und kein kompletter Fail.

      Du verwendest das F-Wort schon wieder :)

      Das hier funktioniert übrigens auch:

      echo htmlspecialchars(print_r(array('foo', 'bar'), fail));

      Aufgrund des typecastings ist fail auch true ;)

    2. Hallo Sven Rautenberg,

      auch an Dir ein Dankeschön für die Erklärungsversuche!
      Leider habe ich auch nach mehrmaligen Lesen es nicht wirklich verstanden.
      Also habe ich einfach mal drauf los probiert (gesamt fast 5 Std.).
      Folgender Code zeigt schon mal die richtige Endausgabe an:

      Eingabe über Textarea:
      ' " & < >

      Ausgabe über PHP Code:
      echo "<pre>\r\n";
      echo htmlspecialchars(print_r($_POST,1), ENT_QUOTES);
      echo "</pre>\r\n";

      Ausgabe auf der PHP Seite:
      Array
      (
        [textarea] => ' " & < >
      )

      Ausgabe im Html Quelltext:
      Array
      (
        [textarea] =&gt; &#039; &quot; &amp; &lt; &gt;
      )

      Bin ich auf der richtigen Spur oder ist das immer noch falsch?
      Danke für eure Antworten!

      Gruß,

      Sub

      1. Hallo Sub,

        Ausgabe über PHP Code:
        echo "<pre>\r\n";
        echo htmlspecialchars(print_r($_POST,1), ENT_QUOTES);
        echo "</pre>\r\n";

        du hast den Hinweis von Sven gar nicht beachtet.
        Das print_r() hat in htmlspecialchars nichts zu suchen.

        Grüße, Matze

        1. Hi!

          echo "<pre>\r\n";
          echo htmlspecialchars(print_r($_POST,1), ENT_QUOTES);
          echo "</pre>\r\n";

          du hast den Hinweis von Sven gar nicht beachtet.
          Das print_r() hat in htmlspecialchars nichts zu suchen.

          Doch, genau so ist das richtig. Sven schrieb nur anfangs etwas unverständlich. Nach dem ersten Teil seiner Antwort wollte ich es ihm schon als Fehler ankreiden, aber er ging dann doch noch auf den Unterschied ein, wenn man print_r() als zweitem Parameter einen zu true kompatiblen Wert übergibt.

          Allerdings muss man den Aufwand mit dem ENT_QUOTES gar nicht treiben, denn sowohl ' als auch " kann problemlos unmaskiert im HTML-Code stehen. Nur wenn es darum geht, Attribut-Werte zu notieren, muss man " und ' berücksichtigen, je nachdem, wie man den Attribut-Wert einfasst. Aber wie sinnvoll ist es, die Ausgabe von print_r() in ein Attribut zu packen?

          Lo!

          1. Hey!

            Doch, genau so ist das richtig. Sven schrieb nur anfangs etwas unverständlich.

            Ja, du hast es sogar noch mal deutlicher "erklärt" -.-

            Allerdings muss man den Aufwand mit dem ENT_QUOTES gar nicht treiben, denn sowohl ' als auch " kann problemlos unmaskiert im HTML-Code stehen.

            Ich verstehe die Reihenfolge auch nicht so ganz.
            Mir erscheint es unlogisch $_POST von Haus aus zu maskieren und das Array als String zu übergeben nur um es anschließend auszugeben.
            Bei der Ausgabe im HTML ist die Maskierung von ', wie du ja auch meintest, sinnfrei und woanders sehe ich keinen Zusammenhang zu htmlspecialchars.
            Ich würde die Ausgabe, vom Gefühl her, anders gestalten. Das scheint mir sehr konfus.

            Aber danke nochmal für den Hinweis, das ist so ungewöhnlich, dass ich es mir beim ersten mal nicht einmal gemerkt habe ;D

            Grüße, Matze

            1. Hi!

              Allerdings muss man den Aufwand mit dem ENT_QUOTES gar nicht treiben, denn sowohl ' als auch " kann problemlos unmaskiert im HTML-Code stehen.
              Ich verstehe die Reihenfolge auch nicht so ganz.
              Mir erscheint es unlogisch $_POST von Haus aus zu maskieren und das Array als String zu übergeben nur um es anschließend auszugeben.

              Es geht darum, eine Kontrollausgabe des Inhalts von $_POST zu erstellen und diese im Kontext HTML auszugeben - hier genauer gesagt als Inhalt eines pre-Elements. print_r($_POST, true) erzeugt die Kontrollausgabe. Wenn allerdings in ihr < oder & vorkommen, kann das einen Browser zum Interpretieren statt Nur-Anzeigen veranlassen. Deshalb muss man diese beiden Zeichen HTML-gerecht maskieren. htmlspecialchars() tut dies, und obendrein auch noch > und ", was hier aber nicht weiter stört, wenn es das nicht täte.

              Bei der Ausgabe im HTML ist die Maskierung von ', wie du ja auch meintest, sinnfrei und woanders sehe ich keinen Zusammenhang zu htmlspecialchars.

              < und & wird benötigt.

              Ich würde die Ausgabe, vom Gefühl her, anders gestalten. Das scheint mir sehr konfus.

              Einfacher geht es eigentlich nicht. Man kann nur noch/dann auf das htmlspecialchars() verzichten, wenn man kein HTML in den $_POST-Werten erwartet. An dieser Stelle darf man das ruhig so lax handhaben, denn es geht nur um eine Kontrollausgabe beim Debuggen, mit selbst eingegebenen Werten und nicht um eine produktive Anwendung (anzunehmenderweise).

              Lo!

              1. Hey dedlfix,

                < und & wird benötigt.

                im OP war die eigentliche Frage doch:

                "Warum wird das einfache Anführungszeichen nicht Umgewandelt?"[sic]
                Wie festgestellt, ist das aber überflüssig (im HTML-Kontext).
                Erinnert mich irgendwie an addslashes() ;)

                An dieser Stelle darf man das ruhig so lax handhaben, denn es geht nur um eine Kontrollausgabe beim Debuggen, mit selbst eingegebenen Werten und nicht um eine produktive Anwendung (anzunehmenderweise).

                Stimmt. Ich schreibe gewohnheitsmässig auch für Kontrollausgaben Schleifen um evtl. Fehler im Detail leichter zu finden.
                Das sind z.B. Tippfehler bei Input-Elementen als Array(s). Da kommt schon mal ein imput[] statt input[] an.

                Da ich den Aufwand mit ENT_QUOTES aber auch immer noch nicht nachvollziehen kann, es sei denn wirklich nur um zu schauen "ob es funktioniert", klinke ich mich jetzt mal wieder aus. Das Problem wurde ja gelöst und daher interessiert mich die Intention des OP auch gar nicht weiter.

                Grüße, Matze

  3. Hello,

    ich habe ein Problem bei der Ausgabe des $_POST Arrays mit htmlspecialchars und ENT_QUOTES!

    Beispiel:

    Ich gebe in eine textarea auf seite1.php folgendes ein:

    ' " & < >

    Dieser Wert wird auf die seite2.php gesendet und mittels nachfolgenden Code ausgegeben:

    <?php
    echo "<pre>\r\n";
    echo htmlspecialchars(print_r($_POST, ENT_QUOTES));
    echo "</pre>\r\n";
    ?>

    Da hast Du ein echtes Problem mit der Klammersetzung und er Zuordnung der Argumente zu den einzelnen Funktionen. Es sollte besser heißen:

    <?php
            echo "<pre>\r\n";
            echo htmlspecialchars(print_r($_POST, 1),ENT_QUOTES);
            echo "</pre>\r\n";
        ?>

    Hatte ich Dir den fehlerhaften Code mal geschrieben? Dann entschuldige bitte. So müsste er jetzt aber passen.

    Bitte immer die Doku dazu lesen und nichts ungeprüft glauben :-))

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de