Nick: Sonderzeichen richtig speichern

Moin an alle,

laut ASCII-Tabelle wird das Zeichen & als %26 richtig interpretiert.

Wenn also ein User das &-Zeichen in meinem Formular manuell eingibt, wandel ich dieses in %26 um. Das erlaubt mir dann auch diese Variable an andere Scripte zu übergeben. Letztendlich soll die Eingabe in einer MySql-Datenbank gespeichert werden. Dort wird natürlich nun das Zeichen %26 gespeichert, was natürlich nicht sein soll.

Ich dachte mit [...$variable=htmlspecialchars($variable);...] wird das ganze richtig abgespeichert. Ist aber nicht so.

Was muss ich also mit meiner Variable machen, bevor ich Sie in meiner Datenbank speicherer?

thx

Nick

  1. laut ASCII-Tabelle wird das Zeichen & als %26 richtig interpretiert.

    Deine Tabelle ist fehlerhaft - & ist in ASCII das mit Dezimal 38 und Hexadezimal 26 zu finden, der Unicode-Codepoint ist U+0026.

    Eine %-Codierung gibt es in ASCII nicht - du verdrehst hier irgendwas mit URL-Encoding.

    Wenn also ein User das &-Zeichen in meinem Formular manuell eingibt, wandel ich dieses in %26 um.

    Warum? Das Umwandeln für den Zeitraum der Kommunikation von Client zu Server übernehmen Client und Server selbsttätig - bei dir am Server kommt wieder ein & an dass du 1:1 so in dei Datenbank schreiben kannst.

    Das erlaubt mir dann auch diese Variable an andere Scripte zu übergeben.

    Es gibt sicher Kontexte in denen % nicht erlaubt ist - z.B. im Kontext URL weil er hier für das %-Encoding verwandt wird.

    Letztendlich soll die Eingabe in einer MySql-Datenbank gespeichert werden. Dort wird natürlich nun das Zeichen %26 gespeichert, was natürlich nicht sein soll.

    Richtig - darum unterlasse das unsinnige URL-Encoding und speichere Kontextneutral in der Datenbank

    Ich dachte mit [...$variable=htmlspecialchars($variable);...] wird das ganze richtig abgespeichert. Ist aber nicht so.

    Hier wechselst du in den Kontext HTML - du befindest dich aber immer noch in einem Neutralen Kontext wo du höchstens syntaktische Eigenheiten des DBMS beachten musst.

    Was muss ich also mit meiner Variable machen, bevor ich Sie in meiner Datenbank speicherer?

    Je nach DBMS jagst du sie durch eine Funktion, die alle für die Abfragesprache spezifischen Zeichen entsprechenden den Vorgaben maskiert.

    Im Fall von MySQL ist das z.B. in PHP die Funktion mysql_real_escape_string() - sofern es sich um einen String handelt.

    Diesen Lesestoff solltest du dir _unbedingt_ zuführen, bevor du weitere Überlegungen anstellst: Artikel:Kontextwechsel

    1. mhh...

      dann muss ich das wohl nochmal genauer erklären.
      Sobald der User seine Eingaben getätigt hat, wird alles an ein save.php-Script gesendet. Dort werden dann alle Variablen auf gültigkeit überprüft. Ist alles richtig, werden die Eingaben in die Datenbank gespeichert ist etwas fehlerhaft, schicke ich den ganzen kram mit header location zurück an das formular. Dabei setze ich sämmtliche Usereingaben mit einem ; getrennt in eine Variable. Das Formular empfängt also eine etwas längere Variable, in der die begriffe mit ; getrennt sind.

      Durch die list() split() Funktionen drösel ich den ganzen kram auf und gebe dem User seine eingaben wieder vor mit dem Zusatz, wo ein Fehler enthalten ist etc.

      Das Problem ist nun, wenn der User das & Zeichen irgendwo verwendet, wird durch das zurückgeben der Variablen alles zerschossen. Daher - war meine Idee - scanne ich die Variablen nach dem &-Zeichen und ersetze es durch %26 (oder was das jetzt war). Somit klappt die Rückgabe der Variablen und sie werden auch richtig - also als & - dargestellt.

      Nur beim speichern haut er da jetzt halt %26 rein.

      Ich hoffe man konnte mir soweit folgen...

      thx

      1. Durch die list() split() Funktionen drösel ich den ganzen kram auf und gebe dem User seine eingaben wieder vor mit dem Zusatz, wo ein Fehler enthalten ist etc.

        Was stört dich an dem bereits sauber getrennten Werten aus $_POST?

        Ich hoffe man konnte mir soweit folgen...

        Ja ich kann folgen, aber mit läuft es grade eiskalt den Rücken runter :)

        Was ein Affenformular ist, weißt du?

        Sobald du in einem Formular irgendwas mit header() machst damit es überhaupt funktioniert, hast du potentiell irgendwas falsch gemacht.

        1. Was ein Affenformular ist, weißt du?

          Genau das mache ich doch!
          Ich Prüfe die Variablen auf Gültigkeit und setze dem User so lange sein Formular wieder vor, bis alle Variableln richtig sind.

          Da das Formular mit einer Funktion aus meiner Index aufgerufen wird, konnte ich weder _POST noch _GET verwenden.
          Also übergebe ich zwei Variablen mit der Funktion: $error und $variablen

          Anhand des $errors gibt das Fomrular den Fehler aus und hinter $variablen verberen sich die Eingaben des Users. Das ist vollkommen übersichtlich und strukturiert - da brauch es Dir nicht kalt den Rücken herunter laufen ;)

          Es wird IMMER! die index.php aufgerufen.

          Aber mir scheint leider, dass wir hier eher am Problem vorbei reden, als eine Lösung zu finden...

          Ich wollte mit den ganzen Details ja keine Gänsehaut verursachen, sondern einfach nur, dass man meine Handlung - das & in %26 zu ändern - nachvollziehen kann.

          cu

          1. Was ein Affenformular ist, weißt du?

            Genau das mache ich doch!

            Offenbar nicht, denn scheinbar ist das Script welches die Überprüfung vornimmt nicht dasselbe wie jenes, welches das Formular anzeigt - ansonsten bräuchtest du die header()-Funktion nicht.

            Ich Prüfe die Variablen auf Gültigkeit und setze dem User so lange sein Formular wieder vor, bis alle Variableln richtig sind.

            Da das Formular mit einer Funktion aus meiner Index aufgerufen wird, konnte ich weder _POST noch _GET verwenden.

            $_POST und $_GET sind superglobal, die stehen idR. überall zur Verfügung - unabhängig ob du eine Funktion aufrufst oder irgendwo in der 10. Methode einer Instanz einer verschachtelten Klasse bist.

            Es wird IMMER! die index.php aufgerufen.

            Wo ist dann das Problem? Wenn index.php die anderen Scripte einbindet und deren Funktionen aufruft, stehen dort genauso die Superglobalen Arrays zur Verfügung.

            Aber mir scheint leider, dass wir hier eher am Problem vorbei reden, als eine Lösung zu finden...

            Ja, weil ich schlichtweg nicht verstehe, was du machst :)

            Ich wollte mit den ganzen Details ja keine Gänsehaut verursachen, sondern einfach nur, dass man meine Handlung - das & in %26 zu ändern - nachvollziehen kann.

            Ich kann es aber immer noch nicht nachvollziehen - in einem Affenformular ist es absolut nicht notwendig (aus welchen Gründen auch immer) irgendwelche Würste aus Variablen- und Wertpaaren zusammenzubauen.

            Solche Würste braucht man idR. nur bei Ajax-Formuaren und dafür gibts Serialisierungsfunktionen (in beide Richtungen) die sich um solche Dinge kümmern.

      2. mhh...

        Genau ;-)

        dann muss ich das wohl nochmal genauer erklären.
        Sobald der User seine Eingaben getätigt hat, wird alles an ein save.php-Script gesendet. Dort werden dann alle Variablen auf gültigkeit überprüft. Ist alles richtig, werden die Eingaben in die Datenbank gespeichert ist etwas fehlerhaft, schicke ich den ganzen kram mit header location zurück an das formular. Dabei setze ich sämmtliche Usereingaben mit einem ; getrennt in eine Variable. Das Formular empfängt also eine etwas längere Variable, in der die begriffe mit ; getrennt sind.

        das ist schonmal ein etwas unschicklicher Ansatz, weil: Der User könnte ja auch ein ";" eingeben und damit ist deine Datenstruktur kaputt.

        Durch die list() split() Funktionen drösel ich den ganzen kram auf und gebe dem User seine eingaben wieder vor mit dem Zusatz, wo ein Fehler enthalten ist etc.

        Das Problem ist nun, wenn der User das & Zeichen irgendwo verwendet, wird durch das zurückgeben der Variablen alles zerschossen.

        Same issue as above.

        Daher - war meine Idee - scanne ich die Variablen nach dem &-Zeichen und ersetze es durch %26 (oder was das jetzt war). Somit klappt die Rückgabe der Variablen und sie werden auch richtig - also als & - dargestellt.

        Eine zeichenorientiere Strukturierung ist Mist. Zumal sich bei Deinem "Eigenbau" mit den Zeichen "&" und ";" Überschneidungen ergeben mit einer Zeichenorientierten Strukturierung, die mit enctype="application/x-www- form-urlencoded" ohnehin gemacht wird, da haben '&' und ';' schon Sonderfunktionen.

        Nur beim speichern haut er da jetzt halt %26 rein.

        Strukturiere Deine Daten unabhängig von Zeichen, die auch ein Benutzer eingeben kann, somit ist und bleibt alles konsistent.

        Horst Heizer

        --
        Auch wenn keine Kohle im Haus ist, richtig heizen will gelernt sein.
        1. Strukturiere Deine Daten unabhängig von Zeichen, die auch ein Benutzer eingeben kann, somit ist und bleibt alles konsistent.

          Das scheint mir auch eher ein Richtiger Weg zu sein...
          ... ist nur leider nicht mal eben aus den Ärmel geschüttelt...

          Da muss man wohl nochmal die Ärmel hochkrämpeln.

          thx

          1. hi,

            Strukturiere Deine Daten unabhängig von Zeichen, die auch ein Benutzer eingeben kann, somit ist und bleibt alles konsistent.

            Das scheint mir auch eher ein Richtiger Weg zu sein...
            ... ist nur leider nicht mal eben aus den Ärmel geschüttelt...

            Ja, da ist was dran. Idee: erzeuge eine Datenstruktur als Sammlung von Referenzen auf $_POST oder $_GET im ['detail']. Infolge Referenzen werden die Daten nicht unnütz kopiert und Du hast mit einer eigenen Struktur alles schön im Überblick.

            Da muss man wohl nochmal die Ärmel hochkrämpeln.

            Mit einem guten Lösungsansatz geht alles ruckzuck. Mal überschlafen, morgen ist nur noch Tippen angesagt ;-)

            Hotti

            --
            Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
  2. Hallo,

    laut ASCII-Tabelle wird das Zeichen & als %26 richtig interpretiert.

    nö, %26 ist die Repräsentation des Zeichens & im URL-Kontext.

    Wenn also ein User das &-Zeichen in meinem Formular manuell eingibt, wandel ich dieses in %26 um.

    Warum? Das macht doch schon der Browser des Formularausfüllers. Und in deinem Script kommt das Zeichen wieder sauber im Klartext an, weil der Server die Codierung ordnungsgemäß rückgängig macht.

    Das erlaubt mir dann auch diese Variable an andere Scripte zu übergeben.

    Wie? Wozu? Warum die URL-Codierung an einer Stelle, für die sie gar nicht gedacht ist?

    Letztendlich soll die Eingabe in einer MySql-Datenbank gespeichert werden.

    Das ist wieder eine andere Geschichte; bei der Übergabe an die DB sind deren Regeln zu beachten. Stringwerte werden z.B. mit mysql_real_escape_string() maskiert (ich gehe einfach mal von mySQL aus).

    Dort wird natürlich nun das Zeichen %26 gespeichert

    Die drei Zeichen '%', '2' und '6', um genau zu sein. Klar, wenn du sie so im String hast.

    Ich dachte mit [...$variable=htmlspecialchars($variable);...] wird das ganze richtig abgespeichert. Ist aber nicht so.

    Raten ist keine gute Strategie. Daten müssen immer dann maskiert oder codiert werden, wenn sie in einen anderen Kontext gebracht werden, und zwar entsprechend den Regeln dieses Kontextes - nicht "auf Verdacht" nach irgendeiner Vorschrift, die zufällig etwas Ähnliches leistet.

    Was muss ich also mit meiner Variable machen, bevor ich Sie in meiner Datenbank speicherer?

    Nichts. Außer der notwendigen Maskierung mit mysql_real_escape_string().

    So long,
     Martin

    --
    Disziplin: Teppichböden wiederfinden, wenn man sie verlegt hat.
    Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
    1. [...] in einer MySql-Datenbank [...]

      [...] (ich gehe einfach mal von mySQL aus).

      Du Ratefuchs! SCNR

      1. Hallo,

        [...] in einer MySql-Datenbank [...]
        [...] (ich gehe einfach mal von mySQL aus).
        Du Ratefuchs! SCNR

        tja, i bin halt a Käpsele! :-)
        Ehrlich, das stand vorhin noch nicht drin! Ganz bestimmt nicht! *augenaufreiß*

        Ciao,
         Martin

        --
        Wenn ein Räuber eine deutsche Amtsstube überfällt, welchen Satz kann er sich dann sparen?
        "Keine Bewegung!"
        Selfcode: fo:) ch:{ rl:| br:< n4:( ie:| mo:| va:) de:] zu:) fl:{ ss:) ls:µ js:(
        1. hi,

          tja, i bin halt a Käpsele! :-)

          Bei uns heißen die Knaller ;-)

          Horst Heizer

          --
          Machst Du die Tür nicht richtig zu, zieht es später oder im Nu.