Electronix: Probleme mit dem Charset

Hallo,

ich habe folgendes Problem:
Ich bekomme aus einem formular, welches das Attribut accept-charset="UTF-8" hat, Daten in ein Array. Diese Daten serialisiere ich über php, codiere sie mit base64 und speichere sie in eine Datenbank(mysql, Charset eingestellt, sowohl bei der Datenbank als auch bei der Verbindung(set names 'UTF8').
Später lese ich diese Daten wieder aus, decodiere sie, deserialisiere sie und Lasse sie ausgeben(Charset per HTML auch auf UTF-8). Wenn allerdings Sonderzeichen aus dem Formular gespeichert werden, werden diese nicht korrekt dargestellt. Im fall des 'ß' steht im Quellcode z.B. Ã�

Woran kann das liegen?

Mit freundlichen Grüßen,

Electronix

  1. hi,

    Woran kann das liegen?

    base64. Gib dem Eingabeformular im header die Kodierung utf-8 mit und speichere die Zeichen so wie sie vom Formular kommen in der DB. Genauso kriegst Du die Zeichen da auch wieder raus, für die Ausgabe im Browser den richtigen Header vornweg und gut isses.

    Hotte

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

      base64. Gib dem Eingabeformular im header die Kodierung utf-8 mit und speichere die Zeichen so wie sie vom Formular kommen in der DB. Genauso kriegst Du die Zeichen da auch wieder raus, für die Ausgabe im Browser den richtigen Header vornweg und gut isses.

      Leider kann ich die Daten nicht so speichern, da ich dem USER die Möglichkeit gebe, unbegrenzt viele Werte zu übergeben, und die müssen alle in die DB. Allerdings kann ich ja nicht in der Tabelle unendlich viele Spalten anlegen, um alle Werte zu speichern. Also speichere ich einfach alle Daten in einer Spalte!

      Mit freundlichen Grüßen,

      Electronix

  2. echo $begrüßung;

    Ich bekomme aus einem formular, welches das Attribut accept-charset="UTF-8" hat, Daten in ein Array. Diese Daten serialisiere ich über php, codiere sie mit base64 und speichere sie in eine Datenbank(mysql, Charset eingestellt, sowohl bei der Datenbank als auch bei der Verbindung(set names 'UTF8').

    Etwas base64-kodiertes besteht nur noch aus lateinischen Groß- und Kleinbuchstaben sowie Zifern und +, / und =. Wenn du nicht gerade mit exotischen Kodierungen hantierst, hat das DBMS und die Übergabe nach und von dort keinen Einfluss auf den Inhalt.

    Später lese ich diese Daten wieder aus, decodiere sie, deserialisiere sie und Lasse sie ausgeben(Charset per HTML auch auf UTF-8). Wenn allerdings Sonderzeichen aus dem Formular gespeichert werden, werden diese nicht korrekt dargestellt. Im fall des 'ß' steht im Quellcode z.B. Ã�

    Kommen sie bereits aus dem Formular falsch an oder werden sie erst bei einer Ausgabe-Behandlung verändert? Untersuch das bitte mit Kontrollausgaben (var_dump()). Ebenso ist es zur Fehlersuche hilfreich die einzelnen Veränderungen in den Verarbeitungsschritten (vor der base64-Kodierung und nach der base64-Dekodierung) mit Kontrollausgaben zu verfolgen.

    echo "$verabschiedung $name";

    1. Hallo,

      Kommen sie bereits aus dem Formular falsch an oder werden sie erst bei einer Ausgabe-Behandlung verändert? Untersuch das bitte mit Kontrollausgaben (var_dump()). Ebenso ist es zur Fehlersuche hilfreich die einzelnen Veränderungen in den Verarbeitungsschritten (vor der base64-Kodierung und nach der base64-Dekodierung) mit Kontrollausgaben zu verfolgen.

      Hab grade festgestellt, das die Daten schon falsch aus dem Formular ankommen.
      Wie kann das sein? Ich meine, ich habe das Formular so angelegt:
      <form action="edit_party.php" method="POST" accept-charset="UTF-8">

      Die Ausgabe habe ich so auf UTF-8 gestellt:
      <meta http-equiv="content-type" content="text/html; charset=UTF-8">

      1. echo $begrüßung;

        Hab grade festgestellt, das die Daten schon falsch aus dem Formular ankommen.

        An der Art des "falsch" kann ein geübtes Auge schon recht genau erkennen, was da konkret schief laufen könnte.

        <form action="edit_party.php" method="POST" accept-charset="UTF-8">

        Diese Angabe wird nicht in jedem Fall von jedem Browser korrekt behandelt.

        <meta http-equiv="content-type" content="text/html; charset=UTF-8">

        Diese ist nur ein Ersatz, wenn der gleichnamige HTTP-Header keine charset-Angabe enthält. Vielleicht sendet dein Server eine mit. Prüf das doch mal mit Tools wie der livehttpheaders-Extension für den Firefox.

        echo "$verabschiedung $name";

        1. Hallo,

          »» Hab grade festgestellt, das die Daten schon falsch aus dem Formular ankommen.

          An der Art des "falsch" kann ein geübtes Auge schon recht genau erkennen, was da konkret schief laufen könnte.

          POST /party-planner/edit_party.php?party=13 HTTP/1.1  
          Host: localhost  
          User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de; rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10 (.NET CLR 3.5.30729)  
          Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8  
          Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3  
          Accept-Encoding: gzip,deflate  
          Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7  
          Keep-Alive: 300  
          Connection: keep-alive  
          Referer: http://localhost/party-planner/edit_party.php?party=13  
          Cookie: PHPSESSID=acdad4b628c7af043eb7e601f31932a8  
          Content-Type: application/x-www-form-urlencoded  
          Content-Length: 219  
          name=Testparty&date=2009-05-14+19%3A25&key%5B%5D=Standort&value%5B%5D=Stra%C3%9Fe&key%5B%5D=&value%5B%5D=&value%5B%5D=&value%5B%5D=&guests%5B%5D=&emails%5B%5D=&id_guest%5B%5D=&submit=Speichern
          

          Konkret geht es um das ß in "Straße". Da steht "Stra%C3%9Fe".
          vardump gibt in der Entsprechenden Zeile "Stra�e" aus!

          »» <form action="edit_party.php" method="POST" accept-charset="UTF-8">

          Diese Angabe wird nicht in jedem Fall von jedem Browser korrekt behandelt.

          Wie kann ich es denn besser machen?

          »» <meta http-equiv="content-type" content="text/html; charset=UTF-8">

          Diese ist nur ein Ersatz, wenn der gleichnamige HTTP-Header keine charset-Angabe enthält. Vielleicht sendet dein Server eine mit. Prüf das doch mal mit Tools wie der livehttpheaders-Extension für den Firefox.

          Du siehst, der Server sendet diese Angabe:
          Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
          Mehr hab ich nicht gefunden.

          Ich hoffe, damit lässt sich was anfangen!

          Mit freundlichen Grüßen,

          Electronix

          1. echo $begrüßung;

            » An der Art des "falsch" kann ein geübtes Auge schon recht genau erkennen, was da konkret schief laufen könnte.

            Konkret geht es um das ß in "Straße". Da steht "Stra%C3%9Fe".

            Das ist UTF-8- und URL-kodiert. Soweit so richtig.

            vardump gibt in der Entsprechenden Zeile "Stra�e" aus!

            Das ist etwas befremdlich, denn normal wäre ß, wenn du ein UTF-8-ß als ISO-8859-1 interpretiert ausgibst. Gib das was du da mit var_dump(...) ausgegeben hast auch noch mal mit echo bin2hex(...) aus.

            » »» <form action="edit_party.php" method="POST" accept-charset="UTF-8">
            » Diese Angabe wird nicht in jedem Fall von jedem Browser korrekt behandelt.
            Wie kann ich es denn besser machen?

            Normalerweise reicht es, dass der Server einen Content-Type-HTTP-Header mit charset für die das Formular enthaltende Seite liefert. Ersatzweise ein Meta-Element so wie du es hat.

            Du siehst, der Server sendet diese Angabe:
            Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

            Das was du da gepostet hast war der Request. Nachsehen musst du im Response und zwar eine Runde vorher. Die relevante Zeile beginnt mit Content-Type.

            echo "$verabschiedung $name";

            1. Hallo,

              »» vardump gibt in der Entsprechenden Zeile "StraÃ�e" aus!

              Das ist etwas befremdlich, denn normal wäre ß, wenn du ein UTF-8-ß als ISO-8859-1 interpretiert ausgibst. Gib das was du da mit var_dump(...) ausgegeben hast auch noch mal mit echo bin2hex(...) aus.

              Gesendet wurden "Straße", mit bin2hex wird das ausgegeben:
              53747261264174696c64653b9f65

              »» Du siehst, der Server sendet diese Angabe:
              »» Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

              Das was du da gepostet hast war der Request. Nachsehen musst du im Response und zwar eine Runde vorher. Die relevante Zeile beginnt mit Content-Type.

              Ich weiß nicht, wie ich an den Response rankomme. Tu mir leid. Geht das auch mit LifeHTTPHeaders?

              Mit freundlichen Grüßen,

              Electronix

              1. echo $begrüßung;

                » » vardump gibt in der Entsprechenden Zeile "StraÃ�e" aus!

                Achte mal auf die Längenangabe. Für Straße wäre 7 richtig, weil PHP Bytes zählt, weil es von 1 Zeichen = 1 Byte ausgeht.

                Gesendet wurden "Straße", mit bin2hex wird das ausgegeben:
                53747261264174696c64653b9f65

                Aufgedröselt ergibt das:
                53 74 72 61 Stra
                26 41 74 69 6c 64 65 3b &Atilde;
                9f ist kein darstellbares Zeichen unter ISO-8859-1
                65 e

                Du hast also irgendwo eine Umwandlung der UTF-8-Bytesequenz in HTML-Entities in deinem Verarbeitungsprozess. Diese Umwandlung ist fehlerhaft, weil sie augenscheinlich nach ISO-8859-1-Regeln arbeitet und nicht nach denen von UTF-8. Außerdem ist eine solche Umwandlung nicht notwendig, wenn man durchgehend mit UTF-8 arbeitet. Lediglich die <http://de.selfhtml.org/html/allgemein/zeichen.htm#html_eigene@title=HTML-eigenen Zeichen> müssen bei der Ausgabe in Richtung HTML berücksichtigt werden.

                Ich weiß nicht, wie ich an den Response rankomme. Tu mir leid. Geht das auch mit LifeHTTPHeaders?

                Diese Extension liefert beides. In dem Fenster/Tab, in dem der gesamte Verkehr zu sehen ist, ist in einem Abschnitt die URL, der Request und die Response dazu zu sehen, jeweils durch eine Leerzeile getrennt.

                echo "$verabschiedung $name";

                1. Hallo,

                  Du hast also irgendwo eine Umwandlung der UTF-8-Bytesequenz in HTML-Entities in deinem Verarbeitungsprozess. Diese Umwandlung ist fehlerhaft, weil sie augenscheinlich nach ISO-8859-1-Regeln arbeitet und nicht nach denen von UTF-8. Außerdem ist eine solche Umwandlung nicht notwendig, wenn man durchgehend mit UTF-8 arbeitet. Lediglich die <http://de.selfhtml.org/html/allgemein/zeichen.htm#html_eigene@title=HTML-eigenen Zeichen> müssen bei der Ausgabe in Richtung HTML berücksichtigt werden.

                  Vielen Dank, das war tatsächlich der Fehler! Ich entwerte die HTML-Zeichen jetzt einfach manuell.
                  Danke schön!

                  Mit freundlichen Grüßen,

                  Electronix