PHP und UTF-8 - eine Anleitung, Exkurs: Wenn die DB durcheinander gerät

Manchmal kommt es vor, dass der Import von Daten in die DB fehlschlägt, und man trotz korrektem UTF-8 wieder mit verhunzten Umlauten zu tun hat. In diesem Fall kann die CONVERT-Funktion von MySQL in Verbindung mit BLOB-Spalten hilfreich sein.

Hier ist ein entsprechender Test-Case:

CREATE TABLE test (
  id integer unsigned NOT NULL auto_increment,
  content varchar(45) NOT NULL,
  PRIMARY KEY  (`id`)
) DEFAULT CHARSET=utf8;

INSERT INTO test (content) VALUES ('Köln');

Dies erzeugt eine Tabelle, in dessen UTF-8-Spalte “content” eine nach UTF-8 konvertierte ANSI-Version von “Köln” steht:

SELECT * FROM test;
id  |   content
--------------------
1   |  Köln

Diese Spalte soll nun so konvertiert werden, sodass dort korrekt “Köln” steht.

Dazu wird nun zunächst einmal eine temporäre Spalte erzeugt, die den konvertierten Inhalt aufnimmt. Diese Spalte ist zunächst Latin1!

ALTER TABLE test
  ADD COLUMN c TEXT CHARACTER SET latin1;

Nun konvertieren wir den verhunzten UTF-8-Inhalt zunächst einmal nach Latin1:

UPDATE test SET c = CONVERT(content USING latin1);

SELECT * FROM test;
id  |   content  |  c
------------------------------
1   |  Köln     |  Köln

Die Spalte “c” enthält nun im Prinzip unser UTF-8 Ergebnis, wenn nur die einzelnen Bytes betrachtet werden. Es müsste nur der Zeichensatz geändert werden, ohne dabei eine Konvertierung durchzuführen.

Dies geht über den Umweg eines BLOB-Feldes:

ALTER TABLE test MODIFY COLUMN c BLOB;
ALTER TABLE test MODIFY COLUMN c TEXT CHARACTER SET utf8;

SELECT * FROM test;
id  |   content  |  c
------------------------------
1   |  Köln     |  Köln

Et voilá!

Published: June 09 2010