PHP & Unicode

Es ist ein immer wieder heiß diskutiertes und oft gewünschtes PHP-Feature. Das „Traumpaar“ PHP und Unicode sollte mit PHP6 Einzug halten. Geschehen ist seitdem nicht sehr viel. PHP 6 wurde zu PHP 5.3 umbenannt und eine vollwertige Unicode-Unterstützung fiel erstmal raus 🙁

Nun müssen wir mit jenen Funktionen leben, die wir aktuell besitzen. Die Auswirkungen sind oftmals erst auf den zweiten Blick sichtbar.

<?php

  echo wordwrap('ä....');

Das obige Beispiel als Grundlage und als UTF8-kodierte Datei angenommen – wann wird wordwrap bei angenommenen 80 Zeichen in Form einzelner ä’s umbrechen?

Der Default-Wert liegt bei 75 Zeichen. Normalerweise sollte also nach 75 Zeichen ein Umbruch erfolgen. Dieser wird jedoch bereits viel früher eingefügt. Und zwar nach 40 Zeichen.

UTF8-Zeichen können im schlechtesten Fall bis zu 4 Byte belegen. Ein „ä“, wie in unserem Fall, benötigt 2 Zeichen. Nachdem wordwrap byteweise – und nicht etwa zeichenweise – zählt, wird der Umbruch viel zu früh eingefügt. Da können PHP-Entwickler wirklich nur neidisch in die Java-Ecke sehen, denn hier war die Unicode-Unterstützung von Anfang an dabei.

Das Problem äußert sich aber nicht nur bei der Funktion word_wrap. Im Prinzip tritt es überall auf, wo Zeichen gezählt und Strings verarbeitet werden.

Nun kennt man evtl. bereits die Multi-Byte-Funktionen von PHP. Deren Funktionsnamen beginnen mit „mb_“ wie beispielsweise mb_strlen(). Es ist also nicht ganz so schlimm um PHP bestellt, wie man zunächst glauben möchte. mb_strlen() kann mit UTF8-Strings umgehen und erkennt dann auch Umlaute mit der korrekten Länge.

Leider bietet die MultiByte-Erweiterung nicht alle gängigen, nötigen Funktionen an. „wordwrap()“ ist ein gutes Beispiel hierfür. Oftmals sind es aber genau jene Funktionen, die man nur allzugerne vergisst. Darüber hinaus reihen sich sprintf, vprintf und weitere in die Problemgruppe ein. Oftmals hilft dann nur die Eigenimplementierung unter Zuhilfenahme der MultiByte-Funktionen.

Fazit: Wer Strings in PHP verarbeitet und auf UTF8 setzt (beispielsweise i.d. Datenbank oder als PHP-Dateiformat), sollte Stringoperationen immer auch einmal mit Sonderzeichen durchtesten und wenn möglich die Multi-Byte-Extension in Betracht ziehen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *