Ankündigung

Einklappen
Keine Ankündigung bisher.

mysqli_real_escape_string() de-escapen?

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • psoido
    hat ein Thema erstellt mysqli_real_escape_string() de-escapen?.

    mysqli_real_escape_string() de-escapen?

    Hi, heute eine Frage zu mysqli_real_escape_string(). Damit habe ich bisher eher sehr selten zu tun gehabt. Die Frage ist, wenn alle Daten bei INSERT INTO oder UPDATE per mysqli_real_escape_string() in die Datenbank geschrieben wurden/werden, (wobei das "wurden" nicht 100 pro sicher ist), wie werden dann die "escapes" bei einem SELECT wieder valide de-escaped? Reicht da ein stripslashes(nl2br($variable))? Oder wie macht Ihr das so?

  • hausl
    antwortet
    Zitat von VPh Beitrag anzeigen
    Warum liest du nicht einfach in den Links nach die man postet.

    Jede Sprache hat eigene "Syntaxen" und damit auch Zeichen mit Speziellen Syntaxeigenschaften, etc..
    HTML, PHP, SQL, Javascript, URI,...

    Und damit man diese sauber in andere "Sprachen" rüber bringen kann muss man den jeweiligen Kontextwechsel korrekt behandeln. PHP bietet dafür netterweise schon alles was man braucht.

    Mehr gibt es dazu eigentlich nicht zu sagen, nur die Zeichen also auch die zu verwendeten Funktionen sind je nach Wechsel individuell.

    Ansonsten... Kennt man einen, kennt man alle.

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    Das sind keine "PHP Characters". Es sind Characters.

    https://en.wikipedia.org/wiki/Character_(computing)

    Einen Kommentar schreiben:


  • psoido
    antwortet
    Zitat von hellbringer Beitrag anzeigen
    HTML ist wieder eine komplett neue Ebene. Du solltest erstmal Schritt für Schritt einzelne Dinge verstehen, statt kreuz und quer alles in einen Topf zu werfen. Wenn du jetzt noch mit HTML anfängst und noch nicht mal Computergrundlagen verstanden hast, wird das Chaos nur größer.
    Ne du, die Welt ist komplex, und ich habe nicht vor sie einfacher zu machen!
    ... ich hatte nur im example oben den Unterschied zwischen double quotes"\n" und single quotes '\n' in PHP nicht beachtet. sorry.
    Vielleicht so?
    PHP Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    HTML ist wieder eine komplett neue Ebene. Du solltest erstmal Schritt für Schritt einzelne Dinge verstehen, statt kreuz und quer alles in einen Topf zu werfen. Wenn du jetzt noch mit HTML anfängst und noch nicht mal Computergrundlagen verstanden hast, wird das Chaos nur größer.

    PHP-Code:
    <form method="post">
        <textarea name="text1"><?= 'foo\nbar' ?></textarea>
        <textarea name="text2"><?= "foo\nbar" ?></textarea>
        <button type="submit">Submit</button>
    </form>
    <pre><?php

    if ($_POST) {
        
    var_dump($_POST);
    }

    ?></pre>
    Ausgabe:
    Code:
    array(2) {
      ["text1"]=>
      string(8) "foo\nbar"
      ["text2"]=>
      string(8) "foo
    bar"
    }

    Einen Kommentar schreiben:


  • psoido
    antwortet
    achso, weil das \n in <?php "\n" ?> geschrieben steht und nicht in <html> \n </html>.
    HTML-Code:
    <form action="/action_page.php" method="post">
    <textarea name="text">\n</textarea>
    <input type="submit">
    </form>
    PHP-Code:
    <?php
    ... mysqli_real_escape_string($_POST['text']) ...
    ?>
    irgendwie so.

    example:
    PHP-Code:
    var_dump('\n'); // string(2) "\n"
    var_dump("\n"); // string(1) " " 

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    Zitat von psoido Beitrag anzeigen
    Ach hellbringer. Ganz sicher ist \n und Line Feed nicht das gleiche Zeichen, weil ein \n bereits escaped ist
    Und Line Feed sind 9 Zeichen. L, i, n, e, <Space>, F, e, e, d.

    Also worauf willst du hinaus?

    Wenn dort steht "Character \n", dann ist eindeutig ein Zeilenumbruch gemeint, und kein Backslash + n. Weil das wäre dann ein String und kein Character.

    Zitat von psoido Beitrag anzeigen
    und wenn es als mysqli_real_escape_string("\n") in die Datenbank gelangt kein Line Feed ist, sondern "\n",
    Nein, hier gelangt ein Line Feed in die Datenbank.

    Zitat von psoido Beitrag anzeigen
    eben weil es schonm escaped ist und nochmals escaped werden würde.
    Es wurde im PHP-Code escaped, aber der Wert selber ist ein Line Feed und kein Backslash + n. Siehe mein zuvor gepostetes Beispiel:
    PHP-Code:
    var_dump("foo\nbar");
    // string(7) "foo
    // bar" 
    Backslash und n sind verschwunden. Magie!

    Einen Kommentar schreiben:


  • psoido
    antwortet
    Zitat von hellbringer Beitrag anzeigen
    Und ob jetzt \n oder Line Feed steht ist Jacke wie Hose, da mit beiden das gleiche Zeichen gemeint ist.
    Ach hellbringer. Ganz sicher ist \n und Line Feed nicht das gleiche Zeichen, weil ein \n bereits escaped ist und wenn es als mysqli_real_escape_string("\n") in die Datenbank gelangt kein Line Feed ist, sondern "\n", eben weil es schonm escaped ist und nochmals escaped werden würde. Siehe 2 Postings über deinen letzten.

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    Mit SQL hat das alles gar nichts zu tun. Das sind PHP-Stringgrundlagen.
    PHP-Code:
    var_dump("foo\nbar");
    // string(7) "foo
    // bar"

    var_dump("foo\\nbar");
    // string(8) "foo\nbar"

    var_dump('foo\nbar');
    // string(8) "foo\nbar"

    var_dump(<<<HEREDOC
    foo\nbar
    HEREDOC
    );
    // string(7) "foo
    // bar"

    var_dump(<<<'NOWDOC'
    foo\nbar
    NOWDOC
    );
    // string(8) "foo\nbar" 
    Das Escaping in SQL-Code erledigt vollkomm mysqli_real_escape_string(). Es besteht da überhaupt kein Handlungsbedarf da selber rumzumurksen.

    Und das Handbuch finde ich korrekt. Es wird hier ja eindeutig von "Characters" gesprochen. Und ob jetzt \n oder Line Feed steht ist Jacke wie Hose, da mit beiden das gleiche Zeichen gemeint ist. Man könnte auch den Hex-Wert 0A hinschreiben. Wäre auch korrekt.

    Einen Kommentar schreiben:


  • psoido
    antwortet
    Naja, das ist ja genau das was ich schon festgestellt habe. Ein \r oder \n sind bereits die escapten Versionen von den Steuerzeichen r und n, ebenso wie bei regex ein s (\s) und ähnlich. Ohne Backslash werden diese Zeichen als Buchstaben behandelt. Mit Backslash als Steuerzeichen. Und das ist dann das was verwirrt, z.B. in den PHP docs, weil das entsprechende Steuerzeichen nicht \r oder \n ist, sondern r oder n. Beziehungsweise ist es noch viel komplexer, weil es am Ende im Fließtext gar kein r oder n ist, sondern nicht in sichtbaren Zeichen dargestellter Unicode. Also ist das falsch und irreführend:
    Characters encoded are NUL (ASCII 0), \n, \r, \, ', ", and Control-Z.
    https://www.php.net/manual/de/mysqli...ape-string.php
    Weil es müsste heißen:
    Characters encoded are NUL (ASCII 0), n, r, \, ', ", and Control-Z.
    oder noch korrekter:
    Characters encoded are NUL (ASCII 0), Line Feed, Carriage Return, \, ', ", and Control-Z.

    Einen Kommentar schreiben:


  • erc
    antwortet
    Zitat von psoido Beitrag anzeigen
    erc, dann bring das doch mal zu Ende: Wie ist es möglich ein Backslash + n (\n), dass kein Zeilenumbruch sein soll, in die Datenbank zu schreiben?
    Das hab ich oben ausgelassen. Der Backslash kann auch maskiert werden.

    Code:
    SELECT '\\n'
    Das übernimmt im Code aber auch mysql_real_escape_string(). Hier musst du aber aufpassen, PHP verwendet teilweise die selben Escapesequeuenzen. (Es ist genau die selbe Problematik, Daten und Steueranweisungen) Schreibst du im PHP Code \n, kann das u.U. "lustig" werden.

    PHP-Code:
    $sql 'SELECT "\\n"';
    $sql "SELECT '\\\\n'";

    $newline '\n';
    $sql 'SELECT "'.$db->mysql_real_escape_string($newline).'"'
    In allen Fällen kommt die Zeichenkette \n in der Datenbank an.

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    Zitat von psoido Beitrag anzeigen
    Wie ist es möglich ein Backslash + n (\n), dass kein Zeilenumbruch sein soll, in die Datenbank zu schreiben?
    So wie immer: Mit mysqli_real_escape_string() escapen.
    PHP-Code:
    mysqli_report(MYSQLI_REPORT_ERROR);

    $db = new mysqli('localhost''root''''test');
    $db->set_charset('utf8');

    $db->query('
        CREATE TEMPORARY TABLE `test` (
            `id` int(10) NOT NULL AUTO_INCREMENT,
            `value` varchar(255) DEFAULT NULL,
            PRIMARY KEY (`id`)
        ) ENGINE=InnoDB  DEFAULT CHARSET=utf8
    '
    );

    $value 'foo\nbar';

    $db->query("
        INSERT INTO `test` (`value`)
        VALUES ('" 
    $db->real_escape_string($value) . "')
    "
    );

    $result $db->query("
        SELECT `value` FROM `test`
    "
    );
    var_dump($result->fetch_row()[0]);
    // string(8) "foo\nbar" 

    Einen Kommentar schreiben:


  • psoido
    antwortet
    erc, dann bring das doch mal zu Ende: Wie ist es möglich ein Backslash + n (\n), dass kein Zeilenumbruch sein soll, in die Datenbank zu schreiben?

    Einen Kommentar schreiben:


  • erc
    antwortet
    Zitat von psoido Beitrag anzeigen
    Irgendwie habe ich es jetzt kapiert. \r und \n sind je 1 Zeichen mit sozusagen 2 Bytes.
    Neh, du hast es noch nicht kapiert. SQL ist ein eigens Format/Protokoll/Sprache/was auch immer. Irgendwer hat da mal festgelegt wie diese Format aussehen soll. Unter anderen ist da auch definiert wie "string literale" also Text in SQL anzugeben ist. Da ist zum Beispiel auch definiert, das Zeilenumbrüche mit \n dargestellt werden könne. Jedes Programm, was SQL kann, kennt diese Regeln. Stößt es beim parsen des SQL Queries auf \n, ist das für das Programm kein Backslash und n, sondern ein Zeilenumbruch.
    Was es eventuell schwerer begreifbar macht, ist, dass Text in SQL noch fast genauso aussieht wie Text. Du musst dich an der Stelle von der Vorstellung trennen, dass das Text ist, dass ist SQL. Wenn du Text in einen SQL Query einfügen willst, musst du den Text erst zu SQL konvertieren.

    Hätten sich die SQL-Macher entschieden, dass Text immer hexadezimal kodiert in den Queries angegeben werden muss, wäre das ziemlich klar.
    Z.B. wenn du alle Einträge mit dem Namen "Hallo" suchen willst. Statt "SELECT ... FROM ... WHERE name = 'Hallo'" müsste der Query so ausshen "SELECT ... FROM ... WHERE name = 0x48616c6c6f". Es wäre sofort klar, dass nicht einfach Text in den Query eingesetz werden kann. Du bräuchtest immer eine Funktion, die dir den Text umwandelt. Genau diese Aufgabe übernimmt mysql_real_escape_string().

    Du kannst das auch testen. Die Hex-Schreibweise ist valides SQL. SELECT "Hallo", 0x48616c6c6f; Du bekommst zweimal Hallo. 0x48616c6c6f sieht für uns nicht wie ein Hallo aus, in SQL ist es aber ein Hallo. "Jedes" Programm was SQL kann, wird das auch als Hallo lesen und als Hallo speichern.

    Einen Kommentar schreiben:


  • hellbringer
    antwortet
    Zitat von psoido Beitrag anzeigen
    Irgendwie habe ich es jetzt kapiert. \r und \n sind je 1 Zeichen mit sozusagen 2 Bytes.
    1 Byte pro Zeichen.

    \n entspricht dem Byte 0x0A und \r entspricht dem Byte 0x0D.

    PHP-Code:
    echo bin2hex("\n") . PHP_EOL;
    // 0a

    echo bin2hex("\x0A") . PHP_EOL;
    // 0a

    echo bin2hex(chr(10)) . PHP_EOL;
    // 0a

    echo bin2hex("\r") . PHP_EOL;
    // 0d

    echo bin2hex("\x0D") . PHP_EOL;
    // 0d

    echo bin2hex(chr(13)) . PHP_EOL;
    // 0d 
    Siehe auch: https://de.wikipedia.org/wiki/Steuerzeichen

    Einen Kommentar schreiben:

Lädt...
X