Umstellung auf UTF-8

17.09.2008 Schon seit längerer Zeit programmiere ich neue Seiten im Zeichensatz UTF-8; in letzter Zeit stelle ich ein paar ältere PHP-MySQL-Projekte von ISO-8859-1 auf UTF-8 um - heute waren die Webnotizen dran. Rudy hatte in meinem Forum schon mal eine gute Anleitung für eine Umstellung geschrieben, die ich bei der Gelegenheit hier um ein paar Punkte ergänze.

1. Datenbank

Eine bestehende MySQL-Datenbanktabelle muss nicht umgestellt werden, bei einer Codierung in ISO-8859-1 nimmt sie weniger Platz ein und das kann so bleiben (siehe hierzu auch die Ausführungen von Kristian Köhntopp in MySQL: Zeichensatz-Grundlagen). Die PHP-Scripte müssen der Datenbank nur für jede Datenbankverbindung den Zeichensatz mitteilen, in welchem die Daten (in beide Richtungen) übertragen werden sollen - das kann mit dieser SQL-Abfrage realisiert werden:

mysql_query("SET NAMES 'utf8'");

Bei UTF-8 ist die Funktion addslashes() nicht mehr ausreichend, eine SQL-Injection zu verhindern - stattdessen müssen Strings mit der Funktion mysql_real_escape_string() behandelt werden, bevor sie in eine Abfrage eingefügt werden.

2. HTML

Die Funktion htmlentities() erwartet ohne Zeichensatzangabe ISO-8859-1-Zeichen und sollte deswegen durch htmlspecialchars() ersetzt werden.

Zur Bearbeitung der HTML-Dateien sollte man natürlich einen Unicode-fähigen Editor verwenden - unter Linux ist das der Normalfall - unter Windows empfehle ich Notepad++. Bei PHP-Dateien muss darauf geachtet werden, dass beim Speichern in UTF-8 kein BOM verwendet wird, da dies zu Problemen bei der Ausführung der Scripte führen kann (in Notepad++ unter Format "UTF-8 ohne BOM" markieren).

3. Browser

Dem Browser muss auf jeder Seite der korrekte Zeichensatz mitgeteilt werden, so z.B. im HTTP-Header:

header("Content-type: text/html; charset=UTF-8");

Im XML-Prolog kann die betreffende Angabe theoretisch auch weggelassen werden, da UTF-8 in XML Standard ist:

<?xml version="1.0" encoding="utf-8"?>

Da die Angabe im XML-Prolog nicht von allen Browsern berücksichtigt wird, sollte bei Fehlen des entsprechenden HTTP-Headers der Zeichensatz mit einer Meta-Angabe übermittelt werden:

<meta http-equiv="content-type" content="text/html; charset=utf-8" />

4. Email

Auch Emails mit einem UTF-8 codierten Body benötigen eine entsprechende Header-Angabe

mail("to@exampl.com", "test", "ä ö ü", "From: from@example.org" . "\r\n" . "Content-Type: text/plain; charset=utf-8");

Email-Header wie der Betreff müssen dagegen mit mb_encode_mimeheader() decodiert werden, wenn sie UTF-8-Zeichen enthalten (siehe Kommentar von Robert Bienert)

2 Kommentare / Trackbacks