2007-06-03

Php, MySQL und Unicode

Ein Teufelsding. Hatten wir doch letztens erst den Auftrag für ein fast fertiggestelltes Projekt eine auf latin1 basierende MySQL Datenbank auf Unicode umzustellen. Dies allein ist ja schon ein ziemlicher Kraftaufwand:

  1. Dump der Originaldatenbank erstellen

  2. Im Dump alle Latin1 Einträge auf UTF8 umstellen / ersetzen

  3. Im Kopf des Dumps folgendes hinzufügen, falls es noch nicht vorhanden ist:

    1. /*!40101 SET NAMES utf8 */;

      Dieses hübsche Zeile soll lediglich dafür sorgen, das MySQL die nachfolgenden INSERT-Kommandos möglichst UTF8-kompatibel ausführt

  4. Neue Datenbank erstellen, für die die Connection-Collation, das MySQL-Charset sowie dieBasis-DB-Collation auf utf8_general_ci gesetzt ist. Utf8_general_ci wird von MySQL scheinbar utf8_unicode_ci gegenüber bevorzugt und als Standard für Unicode erfasst.

  5. Dump in die neue Datenbank importieren

  6. … ANT-Skripte eignen sich hier hervorragend!

Wenn man sich nun die neu ersellte Datenbank anschaut, sollten alle Tabellen und Spalteneigenschaften auf utf8_general_ci gesetzt sein. Die enthaltenen Datenbestände sollten auch im richtigen Format liegen.

Jedoch, das juckt das PHP / MySQL Pärchen nicht sonderlich. Die Collations können alle auf Unicode (UTF8) gesetzt sein, die HTML-Header auch. Und trotzdem werden zerschossene Sonderzeichen geliefert. Das könnte einen wahnsinnig machen. Tut es auch. U.a. mich und meinem Kollegen.

Nachdem wir also ein halbes dutzend Versuche und Prototypen zum konvertieren der Daten geschrieben hatten, gingen wir dem Übel an die Wurzel: MySQL.

In der Tat eine faszinierende Sache. MySQL bietet eine Menge Schnittpunkte, um Collations und Charsets zu setzen. Die der Datenbank/Tabellen sind nur ein kleiner Auszug. Dazu kommen dann so tolle Sachen wie:

  • CHARSET für den Client ( character_set_client=x )

  • CHARSET für zu lieferende Query-Ergebnisse ( character_set_results=x )

  • CHARSET für die MySQL / Client - Verbindung ( character_set_connection=x )

All das auf latin1, da wird man doch gaga auf der Suche nach den Problemen bei der enkodierung.

Man könnte nun die entsprechenden Flags in der my.cnf von MySQL abändern. Das funktioniert sogar … für Konsolenzugriffe. PHP spielt da aber nicht mit, da es scheinbar einen feuchten foorz auf die Einstellungen in der my.cnf gibt.

Eine Möglichkeit funktioniert dann jedoch. Und zwar jene, die jedem PHP-Frickler .. eh, ‘schuldigung … PHP-Entwickler bekannt vorkommen müsste: die frickellösung. Anstatt direkt an der Wurzel des Problems arbeiten zu können, sollte man nach jedem MySQL-Connect ( mysql_connect () ) folgendes Query absetzen:

”SET CHARACTER SET utf8”

Ein vormaliges auswählen einer bestimmten Datenbank ist dafür nicht nötig.

Das penetriert die PHP / MySQL Kombination dann auch zu genau dem, was die Einstellungen in der my.cnf schon sagen: Die Daten aus einem Query UTF8-konform an den Client auszuliefern. Und das klappt. So einfach, und des klappt …

Home Writing Rides Travel Photos Journal