Unicode-Hölle: PHP, Apache, Mysql und Symfony in UTF-8

Ich will mein altes ASCII wieder!!! Unicode ist die Hölle. Vielleicht helfen folgende Dinge dem, der damit rumkämpfen will/muss:

  • Im ganzen Pfad muss die Codierung stimmen bzw. gezielt umgewandelt werden. In unserem Beispiel also Dateisystem, Datenbank, (PHP), Applikation und Browser.
  • Glaube nicht was Du siehst! Was angezeigt wird ist wieder aus einer Applikation die irgendwie encodiert.
  • Firefox: View -> Character Encoding ist Dein Freund. Damit sieht man, was der Browser denkt er erhalte und das Umschalten auf 8859-1 kann zeigen, dass man es noch nicht geschafft hat und immernoch das alte Encoding verwendet wird.
  • utf8_encode() und utf8_decode() sind böse! Wenn man die braucht stimmt etwas nicht.

Hier ein paar Hilfen und Tools.

Dateisystem:

locale -a zeigt die Codierungen. Auf Debian kann man mittels dpkg-reconfigure locales einiges umstellen. Hier mal Unicode zu haben schadet nicht.

Konvertierung mit recode:

Folgendes Kommando wandelt eine Datei in ISO88591 in Unicode um:

recode ISO-8859-1..UTF-8 DATEI

Mysql:
Um Daten in UTF-8 abzulegen, muss:

  • das charset stimmen
  • die Verbindung vom Client zum Server stimmen
  • die Datenbank eine Collation „utf8_unicode_ci“ besitzen
  • jede Tabelle eine Collation „utf8_unicode_ci“ besitzen
  • die Daten in UTF-8 abgefüllt sein

Für das Abfüllen eignet sich mysql-query-browser, da dieser schon mit utf-8 arbeiten kann, was bei der Konsole nicht immer ganz sicher ist.

  • Tools: SHOW VARIABLES LIKE ‚character%‘,damit sieht man, wie man unterwegs ist
  • set names utf8 zwingt die Verbindung zu utf8
  • select _utf8’Trällöällä‘ wandelt den String inUTF-8

Apache:

Irgendwo im Conf sollte AddDefaultCharset UTF-8 stehen. Das vereint das Charset über HTTP.

PHP/Browser:

Wenn der Browser kein UTF-8 anzeigen will, kann man das im php.ini umstellen: default_charset = „UTF-8“.

Links

http://www.phpwact.org/php/i18n/charsets ist eine wirklich gute, praktische Einführung in das Problem im Zusammenhang mit PHP.

Symfony/Creole:

Um da mit UTF-8 zu arbeiten muss databases.yml gefüllt werden. KEIN dsn benutzen, denn dann funzts nicht:

all:
  modul:
    class:      sfPropelDatabase
    param:
      phptype:  mysql
      username: dbuser
      password: dbuserpass
      database: modul
      host:     localhost
      encoding: utf8

Ein ähnliches, hässliches Problem bei der Datenbankmigration wird bei Orthogonal Thought beschrieben.