_Philipp_: Verständnissproblem mit der Codierung von Datenübetragungen

Hallo alle miteinander,

ich habe hier ein sehr verwirrendes Problem. Ich arbeite an einer Webanwendung mit Datenbankanbindung via MYSQL. Dabei gehen die vom Benutzer gemachten Eingaben folgenden Weg:

Eingabe ins Formular auf der HTML-Seite, Übertragung der Daten via Ajax, Verarbeitung Server-seitig von einem PHP-Skript und vom selben Skript senden der Daten an die Datenbank via mysql_query();

Nja gut und irgendwo auf diesem Weg werden mir die Sonderzeichen wie ä,ö,ü und ß durcheinander gebracht. Also denke ich mal, dass an einer Stelle die Codierung verändert wird. Die Frage ist jetzt eigentlich, an welchen Stellen kann so was passieren und wie könnte ich das verhindern.

Wenn ich mir die Daten in phpMyAdmin ansehe, sind dort die Sonderzeichen durch so Sachen wie "ü" ersetzt und natürlich bekomme ich auch keine Sinnvollen ausgaben, wenn ich mir Daten aus der Datenbank mit eigenem Skript wieder auslese.

Was zur Verwirrung hinzu kommt ist, dass ich mit einer anderen Anwendung die folgenden Verarbeitungsweg nutzt keine Probleme mit den Sonderzeichen habe:

Beziehen der Daten aus einer XML-Datei durch PHP-Skript, verarbeiten der Daten durch selbiges PHP-Skript und Übertragung dieser Daten in die Datenbank via mysql_query();

Mit diesem Vorgehen, habe ich keine Probleme alle Sonderzeichen werden korrekt dargestellt.

Die Textfelder der Datenbank sind in den beiden Tabellen jeweils mit "latin1_swedish_ci" formatiert.

Ich wäre Dankbar für jeden Tipp.

MFG Philipp

  1. hi,

    ich habe hier ein sehr verwirrendes Problem. Ich arbeite an einer Webanwendung mit Datenbankanbindung via MYSQL. Dabei gehen die vom Benutzer gemachten Eingaben folgenden Weg:

    Eingabe ins Formular auf der HTML-Seite, Übertragung der Daten via Ajax, Verarbeitung Server-seitig von einem PHP-Skript und vom selben Skript senden der Daten an die Datenbank via mysql_query();

    Nja gut und irgendwo auf diesem Weg werden mir die Sonderzeichen wie ä,ö,ü und ß durcheinander gebracht.

    URI-Escape ist das Zauberwort. Workaround Weiter unten

    Hotte

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

      URI-Escape ist das Zauberwort. Workaround Weiter unten

      Danke das war schon die Lösung. Hatte also eigentlich nichts mit der Codierung zu tun, sondern einfach nur dass ich nicht beachtet habe, das bei Ajax anfragen die Sonderzeichen nicht automatisch escaped werden.
      Jedenfalls funktioniert es jetzt.

      Danke für den Hinweiß.

      MFG

  2. Die Textfelder der Datenbank sind in den beiden Tabellen jeweils mit "latin1_swedish_ci" formatiert.

    was spricht dagegen, die Felder in den Tabellen, die Tabellen, die Datenbanken, die Datenbankverbindung, die Scripte und die Benutzereingaben alle in utf-8 zu codieren?

    Was ist eine Zeichencodierung und warum sollte ich mich damit beschäftigen?

    1. was spricht dagegen, die Felder in den Tabellen, die Tabellen, die Datenbanken, die Datenbankverbindung, die Scripte und die Benutzereingaben alle in utf-8 zu codieren?

      Ja das wäre leider ein sehr großer Aufwand, weil die Datenbank schon aus mehreren Tausend Datenreihen besteht und einige Funktionen bereits darüber laufen. Zudem nutze ich die Datenbank nicht alleine.
      Das Problem trat ja auch nur hier bei dieser Anwendung auf. Daher vermute ich, dass die Codierungen an allen Stellen gleich sind und das Problem nur an dem vergessenen escape(); lag.

      MFG

  3. Hello,

    AJAX, bzw. der http://de.wikipedia.org/wiki/XMLHttpRequest arbeiten immer mit UTF-8.
    Das müsstest Du also bei der Anlage Deiner HTML-Seiten, der PHP-Scripte, der Tabellen in der DB usw. berücksichtigen. Also entweder im PHP-Script umcodieren, oder aber alles auf UTF-8 aufbauen.

    Liebe Grüße aus Syburg bei Dortmund

    Tom vom Berg

    --
    Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de
    1. Hello,

      AJAX, bzw. der http://de.wikipedia.org/wiki/XMLHttpRequest arbeiten immer mit UTF-8.

      Nein.

      Hotte

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

        AJAX, bzw. der http://de.wikipedia.org/wiki/XMLHttpRequest arbeiten immer mit UTF-8.

        Nein.

        Und was soll nun dieser nutzlose Einwand? Wenn Du etwas dazu zu sagen hast, dann tus, aber ein loses "Nein" ist überflüssig.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Hello,

          »» > AJAX, bzw. der http://de.wikipedia.org/wiki/XMLHttpRequest arbeiten immer mit UTF-8.
          »»
          »» Nein.

          Und was soll nun dieser nutzlose Einwand? Wenn Du etwas dazu zu sagen hast, dann tus, aber ein loses "Nein" ist überflüssig.

          Habch doch alles hier geschrieben

          Horst

    2. Hello,

      AJAX, bzw. der http://de.wikipedia.org/wiki/XMLHttpRequest arbeiten immer mit UTF-8.

      Tom, zum Verständnis Klicke mal hier

      Du siehst:
      00.00.0000: Datum%20nicht%20g%FCltig

      Das ist die Response vom Server, die hat mit utf8 nichts zu tun. Wenn Du nun das Script ohne Parameter aufrufst und ein ungültiges Datum in das Formular eingibst, landet dieselbe Response (Datum nicht gültig), weil Ajax, über das DOM im Browser. Dort hab ich die Javascript-Funktion "unescape" eingebaut (siehe Quelltext).

      var textarray = unescape(req.responseText);

      Womit der Zeichensalat wieder lesbar gemacht wird. Genau das ist das Problem, worum sich der Programmierer bei Ajax selbst kümmern muss.

      Hotti

      --
      Wenn der Kommentar nicht zum Code passt, kann auch der Code falsch sein.
      1. echo $begrüßung;

        Das ist die Response vom Server, die hat mit utf8 nichts zu tun.

        Die Kodierung der Response legst du selbst fest, und deklarierst sie über die üblichen Stellen (HTTP-Header Content-Type oder zur Not im meta-Element). Bei dir hat sie nichts mit UTF-8 zu tun, weil du sie als ISO-8859-1 und zusätzlich noch URL-kodiert sendest.

        Wenn Du nun das Script ohne Parameter aufrufst und ein ungültiges Datum in das Formular eingibst, landet dieselbe Response (Datum nicht gültig), weil Ajax, über das DOM im Browser. Dort hab ich die Javascript-Funktion "unescape" eingebaut (siehe Quelltext).

        Und warum machst du das so umständlich? Verwende konsequent UTF-8, deklarier das korrekt und du benötigst keinerlei Hin- und Herkodierung.

        echo "$verabschiedung $name";

        1. hi,

          Und warum machst du das so umständlich? Verwende konsequent UTF-8, deklarier das korrekt und du benötigst keinerlei Hin- und Herkodierung.

          Das ist freilich auch mein Reden und so verwende ich konsequent _eine_ Kodierung meiner Wahl von der Tastatur über das Internet zur Datenbank beim Provider und zurück zum Bildschirm des Besuchers.

          Indes: Der Sachverhalt URIencode ist unabhängig von der Zeichenkodierung ISO-8859-1, UTF-8 oder sonstige.

          Btw., die Kodierung kann auch im Apache-Webserver vorgegeben sein.

          Hotti

          --
          Das große 'ß' ist das '?'. Sie glauben es nicht? Drücken Sie [shift] 'ß' :-)
  4. echo $begrüßung;

    Dabei gehen die vom Benutzer gemachten Eingaben folgenden Weg:
    Eingabe ins Formular auf der HTML-Seite,

    Hier ist die Kodierung noch nicht wichtig, beziehungsweise du hast da keinen Einfluss drauf, das ist Angelegenheit zwischen Betriebssystem und Browser.

    Übertragung der Daten via Ajax,

    AJAX hantiert praktisch nur mit UTF-8. Wenn du versuchst, da etwas anderes zu machen, wirst du nicht glücklich damit.

    Verarbeitung Server-seitig von einem PHP-Skript

    Du bekommst also wegen der AJAX-Übertragung die Daten UTF-8-kodiert.

    und vom selben Skript senden der Daten an die Datenbank via mysql_query();

    Und bei der Übertragung zum DBMS solltest du mit diesem explizit aushandeln, welche Kodierung auf der Verbindung verwendet werden soll. Wichtig ist, die angegebene Kodierung auch wirklich zu vewenden. Und selbst festlegen ist besser als sich auf irgendeinen Default-Wert zu verlassen. mysql_set_charset() oder als Ersatz ein "SET NAMES"-Statement sind passende Werkzeuge.

    Und dann müssen die einzelnen (String-)Felder auch noch die Zeichen speichern können, sollten also auch auf UTF-8 gestellt sein. (Tabellen- und Datenbankkodierungen sind nicht maßgebend.)

    Nja gut und irgendwo auf diesem Weg werden mir die Sonderzeichen wie ä,ö,ü und ß durcheinander gebracht.

    Wenn du bisher mit ISO-8859-1 hantiert hast und das partout nicht ändern möchtest, kannst du Umkodierungen vornehmen, die aber prinzipbedingt nicht verlustfrei durchgeführt werden können. Eine mögliche Stelle dafür wäre zwischen AJAX und PHP. Von AJAX mit utf8_decode() und dorthin mit utf8_encode().

    Die beste Empfehlung ist jedoch, sich mit der Problematik grundlegend auseinanderzusetzen und durchweg zu UTF-8 zu greifen.

    Wenn ich mir die Daten in phpMyAdmin ansehe, sind dort die Sonderzeichen durch so Sachen wie "ü" ersetzt und natürlich bekomme ich auch keine Sinnvollen ausgaben, wenn ich mir Daten aus der Datenbank mit eigenem Skript wieder auslese.

    Das bedeutet, das die Daten UTF-8-kodiert zum DBMS gesendet wurden, dieses jedoch annahm, dass es Latin1 bekommt. Damit hast du erst einmal ein Problem, das du lösen musst. Prüfe zunächst, ob alle Umlaute betroffen sind und nicht etwa welche aus Zeiten von vor der AJAX-Implementierung richtig angezeigt werden (im phpMyAdmin). Wenn alles gleich verunstaltet ist, exportier die Daten als SQL-Dump. Nun solltest du doppelt UTF-8-kodierte Daten im Dump vorfinden, denn PMA exportiert ohne iconv- oder recode-Extension immer UTF-8. (Kann man prüfen, indem man die Datei im Browser öffnet, und über das Menü Ansicht->Zeichenkodierung auf ISO-8859-1 stellt und vier Zeichen pro Umlaut sieht oder bei UTF-8 zwei.) Dann brauchst du einen Editor, der die Datei als UTF-8 öffnet und als ISO-8859-1 speichert. Nun hast du nur noch einfach UTF-8-kodierte Daten und kannst beim Import angeben, dass die Kodierung UTF-8 ist. Wenn dir die Kommandozeilentools von MySQL zur Verfügung stehen (Programm mysqldump), kannst du damit exportieren, wobei du als Kodierung Latin1 angeben solltest (da gibt es einen Parameter für). Nun kannst du als UTF-8 importieren.

    Wichtig ist, immer eine Sicherheitskopie anzufertigen beziehungsweise erst einmal mit einer Kopie üben.

    Was zur Verwirrung hinzu kommt ist, dass ich mit einer anderen Anwendung die folgenden Verarbeitungsweg nutzt keine Probleme mit den Sonderzeichen habe:
    Beziehen der Daten aus einer XML-Datei durch PHP-Skript,

    Wie liest du die XML-Daten? Die bekannten XML-Komponenten stellen dir die Inhalte normalerweise auch UTF-8-kodiert zur Verfügung.

    verarbeiten der Daten durch selbiges PHP-Skript und Übertragung dieser Daten in die Datenbank via mysql_query();

    Was auch immer "verarbeiten meint" - vermutlich nichts was die Kodierung ändert - diese beiden Schritte sind ja eigentlich die gleichen wie oben.

    Mit diesem Vorgehen, habe ich keine Probleme alle Sonderzeichen werden korrekt dargestellt.

    Hmm, das hört sich so an, als ob du Mischmasch in den Daten hast. In dem Fall bleibt vermutlich nur eine aufwendige händische Korrektur.

    Die Textfelder der Datenbank sind in den beiden Tabellen jeweils mit "latin1_swedish_ci" formatiert.

    Die Feldkodierung sagt nur aus, welche Zeichen überhaupt aufgenommen werden können. Die Kommunikation von und zum Client bedient sich einer eigenen Kodierungskonfiguration. Wenn beide Einstellungen unterschiedlich sind, kodiert MySQL selbständig zwischen beiden um. (Geht natürlich nicht in jede Richtung verlustfrei.)

    echo "$verabschiedung $name";

    1. Danke für deine Antwort.
      Wie sich herausgestellt hat, lag das Problem zwar daran, dass ich bei dem Ajaxaufruf den escape() der gesendeten Daten nicht beachtet hatte. Aber deine Informationen sind durchaus interessant für mich. Wegen dem zu großen Aufwand jetzt alles noch einmal umzubauen und weil die Datenbank auch noch von anderen verwendet wird, werde ich jetzt keine Codierungsänderungen vornehmen. Es funktioniert ja jetzt auch, nach dem ich den escape() vor dem Versenden der Daten eingebaut habe.
      Aber in Zukunft werde ich darauf achten überall die selbe Codierung zu verwenden.

      MFG