Die Flagge des Marasek

Dekostreifen

English

Aktuell Texte Der Comic Impressum Kalender Suche PHP-Klassen Container-Wizard main.s21

Kategorien

Buch
Computer
Computerspiele
Film
Geschichte
Gesellschaft
Idee
Kunst
Natur
Persönlich
Politik
Programmieren
Religion & Philosophie
Weblog
Weltpolitik
Weltsicht
{{login}}

Leben und lieben mit UTF8

Permalink
Vorheriger: FoveonNächster: Darth Vader
Eingeordnet in: Programmieren

Vor geraumer Zeit habe ich meine Seite auf UTF8 umgestellt. Seither bin ich dazu übergegangen, neue Projekte direkt in Unicode anzulegen und nicht mehr in ISO-8859-1. Das hat den Vorteil, dass ich polnische Namen Wrocław oder Łódź richtig darstellen kann, ohne auf HTML-Entities zurückgreifen zu müssen oder gar ein anderes Characterset zu verwenden (ISO-8859-2). Zwar benötige ich polnische Namen selten auf meiner Seite, zugegeben, aber andererseits befindet sich Deutschland an der Grenze zu ISO-8859-2 und ein nicht unerheblicher Teil der erweiterten EU verwendet diesen Zeichensatz. In meiner Arbeit hatte ich definitiv schon mit Wrocław zu tun (und einer polnischen Tastatur, die uns mal irrtümlich geliefert wurde).

UTF8 hat allerdings auch ein paar Fallen, vor allem im Zusammenspiel mit PHP, das bis Version 5 noch kein UTF8 von Haus aus unterstützt. Auch ist zu beachten, dass die Standardkonfiguration der meisten Software noch ISO-8859-1 bzw Latin1 ist, etwa von MySQL oder Apache.

Webserver

Per default wird meist in ISO-8859-1 ausgeliefert. Dies kann unter PHP mit einem vorangestellten header("Content-Type: text/html; charset=UTF8;"); geändert werden. Für einzelne HTML-Seiten muss man die Webserver-Konfiguration ändern. Es ist zwar auch möglich, <meta http-equiv="Content-Type" content="text/html; charset=UTF8" /> zu verwenden, davon ist aber abzuraten, weil man widersprüchliche Angaben erhalten kann.

PHP

PHP unterstützt, wie gesagt, nativ kein UTF8. Folgendes ist zu beachten:

  • Funktionen wie strlen() liefern falsche Ergebnisse, wenn sie mit einem UTF8-String gefüttert werden, strlen("über") ergibt 5 und nicht 4, da ü zwei Bytes verbraucht. strtoupper() u. ä. werden unvorhergesehene Ergebnisse liefern, da sie die zusammengehörenden Zeichen eines UTF-8-Zeichens als eingenständige Charaktere betrachten.
  • Auf der anderen Seite kann man explode("ü", "hüberdrüber") gefahrlos verwenden
  • generell werden für die Unicode-Zeichen nur Werte über 127 verwendet. Man muss also nicht befürchten, dass bei einem explode("\n", $string) der String an einer falschen Stelle gesplittet wird
  • Texteditoren setzen mitunter einen BOM (Byte Order Mark) an den Anfang einer als UTF-8 definierten Datei. Diese BOMs können dann an den unbequemsten Stellen wieder auftauchen, vor allem bei Klassenbibliotheken, die vor einem Aufruf von header() oder session_register() inkludiert werden, stören sie: da sie vor dem <?php erscheinen, werden sie vom Parser ausgegeben.
  • Vorsicht mit htmlentities. htmlentities wird die Einzelbytes eines Unicode-Zeichens maskieren, anstelle von über wird dann "über" ausgegeben. htmlentities muss htmlentities("über", NULL, "UTF-8") aufgerufen werden (grundsätzlich verwende ich es aber nicht, sondern beschränke mich auf htmlspecialchars())
  • die beschriebenen Probleme mit strlen und Konsorten kann man durch Verwendung der Multibyte-Extension mbstring umgehen (PHP mit --enable-mbstring kompilieren, siehe auch http://www.php.net/mbstring. Um über in ÜBER zu verwandeln, wird dann mb_strtoupper("über", "UTF-8") aufgerufen.
  • unbedingt erwähnen muss ich noch, dass preg seit geraumer Zeit UTF-8 frisst, wenn man den Modifikator /u verwendet. Besonders leistungsfähig sind die Unicode Character Properties (http://www.php.net/manual/de/reference.pcre.pattern.syntax.php), mit denen man gezielt nach bestimmten Zeicheneigenschaften suchen kann, beispielsweise matcht preg_match("/p{L}/u") auf alle Buchstaben im String. Mit preg_split("/P{L}/u"), der Negation, kann man einen String in einen Array zerlegen, der nur noch aus Wörtern besteht.

Datenbank (MySQL)

MySQL hält noch einige "caveats" bereit, auf die ich hinweisen möchte. Generell ist die Benutzung jedoch einfach.

  • Der Zeichensatz kann für den ganzen MySQL-Dienst, eine Datenbank, eine Tabelle oder nur eine Spalte gesetzt werden. Standardmässig läuft der mysqld im latin1-Modus, deswegen wird jede neue Tabelle, so man nichts anderes angibt, auch mit latin1 erstellt.
  • Man kann den Zeichensatz später umändern. Aber: wenn ich eine bestehende latin1-Tabelle auf UTF-8 ummünze, werden die enthaltenen Spalten explizit auf latin1 gesetzt und so beibehalten! Ein effektiver Weg, eine ganze Datenbank zu konvertieren ist, mit dem MySQL-Administrator die Datenbank zu sichern, im Textfile alle Vorkommen von latin1 durch UTF8 zu ersetzen und den Dump zurückzuspielen.
  • Dazu hat noch die Verbindung selbst ein Character Set, per default ebenfalls latin1. Direkt nach dem Verbindungsaufbau muss daher noch ein "SET CHARACTER SET UTF8" und "SET NAMES UTF8" als Query abgesetzt werden. Ansonsten werden die an die Datenbank geschickten UTF-8-Daten in ISO-8859-1 umgewandelt und so in der Datenbank gespeichert - mit dem üblen Nebeneffekt, dass ein 2-Byte-Zeichen dann vier Bytes belegt, weil die Einzelbestandteile beim Speichern wieder in UTF8 umgewandelt werden...
    Allerdings kann man so eine Seite in UTF-8 betreiben und die Datenbank auf latin1 lassen oder umgekehrt. Zu bedenken ist aber, dass bei der Umwandlung UTF-8 zu latin1 immer Information verloren gehen kann, wenn der UTF-8-String Zeichen enthält, zu denen es keine Entsprechung in latin1 gibt.

Kommentieren

Bitte beachten: Kommentare sind nicht sofort sichtbar, sondern werden erst nach einer kurzen Prüfung freigegeben, sofern keine rechtliche Beanstandung vorliegt.
Rechtlich bedenkliche Inhalte werden entweder entschärft oder nicht veröffentlicht.

* Titel  
* Nickname  
* Kommentar