foomaker: UTF-8

Hallo zusammen.

Folgendes Problem:

MySQL-DB ursprünglich mit Kollation 'latin1_swedish_ci' für Datenbank, Tabelle und Felder.

HTML-Skript ursprünglich im head: <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">

So war alles gut. ä, ö, ü, ß und Konsorten wurden brav per <form> in die DB eingetragen, wieder ausgelesen und lesbar (!) dargestellt.

Vorab: http://forum.de.selfhtml.org/archiv/2008/1/t164646/#m1073312 "UTF-Speicherung in MySQL" hab ich gelesen, tipps ohne Erfolg umgesetzt

So, jetzt das eigentliche Dilemma:

In Formularen geben Kunden teilweilse sehr wirre Zeichen an, weil sie unbedingt den spanischen (oder was auch immer) Originalnamen mit einer Tilde über dem n haben wollen.
So klappt das dann aber nicht bei der Suche.
Also wollte ich nun alles komplett auf UTF-8 umstellen: DB und Skripte und Texte.

Texte kein Problem. HTML kein Problem. Nur mit MySQL will das nicht klappen.

Beispiel: Eintrag mit "äöüß" in "alte" DB mit Kollation 'latin...' gemacht. Kollation für DB, Tabelle und Feld auf 'utf8_unicode_ci' geändert. In HTML-Seite ist im meta-tag charset=utf-8 angegeben.

Trotzdem stehen da hartnäckig ���� statt äöüß.

Die Tipps aus o.a. Link haben auch nicht funktioniert.

Was mache ich wohl falsch? Bzw. wie muss ich das anders angehen?

Danke für Tipps.

Der Foomaker

--
Natürlich glaube ich an die Existenz von Ausserirdischen. Schliesslich gibt es ja auch das PERFEKTE SCRIPT.
  1. Hallo

    MySQL-DB ursprünglich mit Kollation 'latin1_swedish_ci' für Datenbank, Tabelle und Felder.

    HTML-Skript ursprünglich im head: <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-15">

    Beispiel: Eintrag mit "äöüß" in "alte" DB mit Kollation 'latin...' gemacht. Kollation für DB, Tabelle und Feld auf 'utf8_unicode_ci' geändert. In HTML-Seite ist im meta-tag charset=utf-8 angegeben.

    Trotzdem stehen da hartnäckig ���� statt äöüß.

    Was mache ich wohl falsch? Bzw. wie muss ich das anders angehen?

    Das Problem ist, dass in die alten Datensätze in der DB immer noch mit ISO-8859-15 kodiert sind. Die Seite wird (offensichtlich mit utf-8 ausgeliefert und die Inhalte aus der DB haben nun nicht mehr die passende Kodierung.

    Direkt nach dem Aufbau der Verbindung mit dem DB-Server kannst du dem Server den gewünschten Zeichensatz mitteilen. Beispielsweise mit folgender Funktion:

    function connect_dbserver($db) {  
    # Datenbankserver kontaktieren  
    $s = mysql_connect($db["host"],$db["user"],$db["pass"]);  
    # Datenbank auswählen  
    $t = mysql_select_db($db["dbase"],$s);  
    if ($s===false or $t===false)  
       {  
       # Server konnte nicht kontaktiert werden bzw.  
       # Datenbank konnte nicht ausgewählt werden.  
       return false;  
       }  
    else  
       {  
       # Teile dem DB-Server mit, dass er die Ergebnisse  
       # der Abfragen in utf-8 ausliefern soll.  
       $q = "[code lang=sql]SET NAMES utf8
    ~~~";  
       $a = mysql\_query($q,$s);  
       if ($a===false)  
          {  
          # Abfrage ist fehlgeschlagen  
          return false;  
          }  
       else  
          {  
          # Absetzen des Queries war erfolgreich,  
          # es wird die Verbindungskennung zur weiteren  
          # Verwendung aus der Funktion zurueckgegeben.  
          return $s;  
          }  
       }  
    } # Ende: connect\_dbserver($db)[/code]  
      
    Alle später im Skript ausgeführten Abfragen werden nun, unabhängig von ihrer in der DB vorliegenden Kodierung, in utf-8 zurückgegeben.  
      
    Tschö, Auge  
    
    -- 
    Die deutschen Interessen werden am Liechtenstein verteidigt.  
      
    [Veranstaltungsdatenbank Vdb 0.2](http://termindbase.auge8472.de/)
    
    1. Hallo auge,

      super.

      Danke.

      Hilft.

      Gruß vom foomaker

    2. echo $begrüßung;

      Beispiel: Eintrag mit "äöüß" in "alte" DB mit Kollation 'latin...' gemacht. Kollation für DB, Tabelle und Feld auf 'utf8_unicode_ci' geändert.
      Das Problem ist, dass in die alten Datensätze in der DB immer noch mit ISO-8859-15 kodiert sind.

      Wenn die Kodierungs-/Kollationsangabe eines Feldes geändert wird, wird dabei auch der Feldinhalt umkodiert. Es gibt danach keine "alten Datensätze". Wenn vorher der Inhalt zur Kodierung passte und in eine Richtung umgestellt wurde, die alle ursprünglichen Zeichen repräsentieren kann, dann gibt es dabei auch keine Probleme.

      echo "$verabschiedung $name";

      1. Hallo

        Beispiel: Eintrag mit "äöüß" in "alte" DB mit Kollation 'latin...' gemacht. Kollation für DB, Tabelle und Feld auf 'utf8_unicode_ci' geändert.
        Das Problem ist, dass in die alten Datensätze in der DB immer noch mit ISO-8859-15 kodiert sind.

        Wenn die Kodierungs-/Kollationsangabe eines Feldes geändert wird, wird dabei auch der Feldinhalt umkodiert. Es gibt danach keine "alten Datensätze".

        Ach, und warum wird genau _deswegen_ hier immer wieder nachgefragt? Und warum wird genau für solche Suituationen immer wieder SET NAMES utf8 empfohlen?

        Wenn vorher der Inhalt zur Kodierung passte und in eine Richtung umgestellt wurde, die alle ursprünglichen Zeichen repräsentieren kann, dann gibt es dabei auch keine Probleme.

        Das habe ich anders erlebt. Da passte eben nach der Umstellung der Kollation garnix.

        Tschö, Auge

        --
        Die Musik drückt aus, was nicht gesagt werden kann und worüber es unmöglich ist zu schweigen.
        (Victor Hugo)
        Veranstaltungsdatenbank Vdb 0.2
        1. echo $begrüßung;

          Wenn die Kodierungs-/Kollationsangabe eines Feldes geändert wird, wird dabei auch der Feldinhalt umkodiert. Es gibt danach keine "alten Datensätze".
          Ach, und warum wird genau _deswegen_ hier immer wieder nachgefragt? Und warum wird genau für solche Suituationen immer wieder SET NAMES utf8 empfohlen?

          SET NAMES und die Kodierung der Felder sind zwei verschiedene Dinge. Die Kodierung der Felder ist unabhängig von der Kodierung, die bei der Kommunikation mit einem Client verwendet wird. SET NAMES stellt die Kodierung der Clientverbindung ein. Die hat auch einen Defaultwert. Wenn du nun annimmst, nach der Umstellung der Feldkodierung die Daten in der Feldkodierung zu erhalten ist das ein Irrtum. Für die Verbindungskodierung gilt immer noch deren (vor)eingestellter Wert. Wenn Feldkodierung und Verbindungskodierung unterschiedlich sind, versucht MySQL die Daten umzukodieren. Das geht natürlich nicht in jede Richtung verlustfrei, aber das ist ein anderes Thema.

          Es gibt immer wieder diese Probleme, weil man meist übersehen hat, die Verbindungskodierung auszuhandeln. Beide Seiten sprechen dann verschiedene Sprachen, weswegen es Probleme beim Interpretieren der Daten gibt.

          Wenn vorher der Inhalt zur Kodierung passte und in eine Richtung umgestellt wurde, die alle ursprünglichen Zeichen repräsentieren kann, dann gibt es dabei auch keine Probleme.
          Das habe ich anders erlebt. Da passte eben nach der Umstellung der Kollation garnix.

          Wenn man ein System nicht verstanden hat, ist es ganz natürlich, dass man Fehler macht. Probier es doch einfach noch einmal. Orientieren kannst du dich dabei an einem Versuch, den ich vor einger Zeit mal unternahm: </archiv/2007/7/t157019/#m1021663>

          echo "$verabschiedung $name";

          1. Hallo

            Vorneweg: Tut mir leid, mich im Ton vergriffen zu haben. Ich war an dem Tag etwas griesgrämig.

            Wenn die Kodierungs-/Kollationsangabe eines Feldes geändert wird, wird dabei auch der Feldinhalt umkodiert. Es gibt danach keine "alten Datensätze".
            Ach, und warum wird genau _deswegen_ hier immer wieder nachgefragt? Und warum wird genau für solche Suituationen immer wieder SET NAMES utf8 empfohlen?

            SET NAMES und die Kodierung der Felder sind zwei verschiedene Dinge. Die Kodierung der Felder ist unabhängig von der Kodierung, die bei der Kommunikation mit einem Client verwendet wird.

            Soweit ist das klar.

            SET NAMES stellt die Kodierung der Clientverbindung ein. Die hat auch einen Defaultwert. Wenn du nun annimmst, nach der Umstellung der Feldkodierung die Daten in der Feldkodierung zu erhalten ist das ein Irrtum. Für die Verbindungskodierung gilt immer noch deren (vor)eingestellter Wert.

            Auch das ist klar. SET NAMES sagt der DB, dass ich bei allen Abfragen _dieser_ (also der aktuellen) Verbindung einen bestimmten Zeichensatz benutzen will.

            Wenn vorher der Inhalt zur Kodierung passte und in eine Richtung umgestellt wurde, die alle ursprünglichen Zeichen repräsentieren kann, dann gibt es dabei auch keine Probleme.
            Das habe ich anders erlebt. Da passte eben nach der Umstellung der Kollation garnix.

            Wenn man ein System nicht verstanden hat, ist es ganz natürlich, dass man Fehler macht.

            Ja, sowas kommt vor. Zumal ich gerade in Sachen MySQL so einiges per trial & error probiere, dazulernen einbegriffen (hoffe ich doch mal ;-)). Dein Beispiel war jedenfalls sehr aufschlussreich.

            Wenn ich also z.B. per phpMyAdmin die Kollation der DB, der Tabelle und der Felder auf einen anderen Zeichensatz umstelle, werden die Feldinhalte auch umgestellt? Etwaige Inkonsistenzen bei der Ausgabe kommen dann daher, dass der Vorgabewert für den Zeichensatz der Verbindung nicht dem Zeichensatz der Feldwerte entspricht?

            Ich hoffe das jetzt richtig verstanden zu haben.

            Tschö, Auge

            --
            Die deutschen Interessen werden am Liechtenstein verteidigt.
            Veranstaltungsdatenbank Vdb 0.2
            1. echo $begrüßung;

              Vorneweg: Tut mir leid, mich im Ton vergriffen zu haben. Ich war an dem Tag etwas griesgrämig.

              Ist mir gar nicht aufgefallen. Vermutlich hatte ich die Lautsprecher ausgeschaltet gelassen.

              Wenn ich also z.B. per phpMyAdmin die Kollation der DB, der Tabelle und der Felder auf einen anderen Zeichensatz umstelle, werden die Feldinhalte auch umgestellt?

              Die Angaben bei Datenbank und Tabelle sind nur Defaultangaben für neu hinzukommende Elemente, wenn diesen keine Angabe explizit mit auf den Weg gegeben wurde. Letzten Endes zählt allein die Einstellung des Feldes. Wenn du Datenbank- und Tabellenkodierung umstellst, ändert sich an den Daten nichts. Es muss schon die Kodierungsangabe jedes Feldes einzeln angefasst werden.

              Etwaige Inkonsistenzen bei der Ausgabe kommen dann daher, dass der Vorgabewert für den Zeichensatz der Verbindung nicht dem Zeichensatz der Feldwerte entspricht?

              Ja, entweder aktuell nicht entspricht oder damals nicht entsprach, als die Daten zum Server gesendet wurden.

              Es ist beispielsweise kein Problem, wenn zwar sowohl Feld- als auch Verbindungskodierung auf Latin1 stehen, der Client aber UTF-8 sendet. Die Bytefolge wird problemlos im Feld abgelegt. Beim Abfragen kommt auch genau die gleiche Bytefolge zurück und kann gemäß UTF-8 interpretieren werden. Doch wenn MySQL die Daten interpretieren soll, sieht es kein ä sondern die beiden Bytes xC3 xA4 und damit à und ¤, weil es sie gemäß Latin1 interpretiert. Bei einer Feldkodierungsänderung in diesem Zustand kommt natürlich auch nur Murks raus. Da muss zunächst der Inhalt der Kodierung angepasst werden. (Ich beschränke mich auf diese allgemeine Aussage, weil die konkrete Vorgehensweise vom Einzelfall und des bisher gemachten Fehlers abhängig ist.)

              echo "$verabschiedung $name";

              1. Hallo

                Wenn ich also z.B. per phpMyAdmin die Kollation der DB, der Tabelle und der Felder auf einen anderen Zeichensatz umstelle, werden die Feldinhalte auch umgestellt?

                ... Letzten Endes zählt allein die Einstellung des Feldes. Wenn du Datenbank- und Tabellenkodierung umstellst, ändert sich an den Daten nichts. Es muss schon die Kodierungsangabe jedes Feldes einzeln angefasst werden.

                Hatt' ich's mir doch gedacht. :-)

                Etwaige Inkonsistenzen bei der Ausgabe kommen dann daher, dass der Vorgabewert für den Zeichensatz der Verbindung nicht dem Zeichensatz der Feldwerte entspricht?

                Ja, entweder aktuell nicht entspricht oder damals nicht entsprach, als die Daten zum Server gesendet wurden.

                Es ist beispielsweise kein Problem, wenn zwar sowohl Feld- als auch Verbindungskodierung auf Latin1 stehen, der Client aber UTF-8 sendet. Die Bytefolge wird problemlos im Feld abgelegt. Beim Abfragen kommt auch genau die gleiche Bytefolge zurück und kann gemäß UTF-8 interpretieren werden. Doch wenn MySQL die Daten interpretieren soll, sieht es kein ä sondern die beiden Bytes xC3 xA4 und damit à und ¤, weil es sie gemäß Latin1 interpretiert.

                Wenn ich bei der Verbindungsaufnahme mit SET NAMES arbeite, wie es meine Funktion tut, kommt dann MySQL mit 'ä' vs. 'Ã und ¤' im Falle des Falles zurecht?

                Tschö, Auge

                --
                Die deutschen Interessen werden am Liechtenstein verteidigt.
                Veranstaltungsdatenbank Vdb 0.2
                1. Moin!

                  Wenn ich bei der Verbindungsaufnahme mit SET NAMES arbeite, wie es meine Funktion tut, kommt dann MySQL mit 'ä' vs. 'Ã und ¤' im Falle des Falles zurecht?

                  Wenn du "SET NAMES utf8" sendest, müssen alle deine Querys in UTF-8 codiert sein. MySQL wird die Zeichen dann erkennen und, falls die Zielspalte eine andere Codierung erfordert, umkodieren. Es gibt da kein 'Ã und ¤'.

                  Ebenso wird ein Query, der in ISO-8859-1 (default) erfolgt, umkodiert, wenn er in einer UTF-8-Spalte gespeichert werden soll.

                  Im zweiten Fall merkt man davon nichts, weil kein Zeichen verlorengeht. Im ersten Fall aber schon.

                  - Sven Rautenberg

                  --
                  "Love your nation - respect the others."