Kategorie-Archiv: New

DOAG in Nürnberg

Zwar muss ich eingestehen, dass ich nicht der größte O..-Fan bin, jedoch hat sich die Firma in den letzten Jahren Sun und MySQL einverleibt. Diese Tatsache kann man hinsichtlich Java- und MySQL-Themen nicht einfach ignorieren.

Eine aufgrunddessen nicht uninteressante Messe findet dieses Jahr  ganz in meiner Nähe in Nürnberg statt: Die DOAG Konferenz (Deutsche Oracle Anwender Gruppe) Den zugehörigen Link findet Ihr hier: http://www.doag.org/konferenz/2011-konferenz-streamdetails.php

Dort gibt es in der Rubrik „MySQL“ einige interessante Vorträge.

PHP String Klasse

PHP und UTF8-String sind wie im vorherigen Artikel beschrieben, immer wieder ein Hindernis. Daher dachte ich mir, warum nicht eine UTF-8 fähige String-Klasse schreiben? Gesagt getan. Hier kann man das Resultat begutachten:

https://github.com/codenaschereien/PHPString/

Das Ganze befindet sich natürlich noch im Anfangsstadium und ist ausbaufähig. Anregungen und Bugmeldungen sind jederzeit willkommen. 😉

Nun noch ein paar kleine Beispiele, die den Sinn der Klasse erläutern sollen:

<?php

$s = 'aöbc';
echo $s[2];

Das Ergebnis ist ein „?“, da das „ö“ an Position 2 mehr als nur ein Byte benötigt. Vorraussetzung dafür ist natürlich, dass man die PHP-Datei auch in UTF-8 speichert. Mit der String-Klasse könnte es nun so aussehen:

<?php

require_once('String.php');
$s = new String('aöbc');
echo $s[2];

Als korrekten Rückgabewert erhalten wir nun „b“. Instanzen der Klasse String können außerdem insgesamt wie ein Array behandelt werden. D.h. schreiben, lesen und sogar unset() funktionieren an allen validen Positionen. Darüber hinaus kann die String-Klasse im Gegensatz zu normalen Strings auch mit foreach iteriert werden:

<?php

require_once('String.php');
$s = new String('aöbc');
foreach($s as $char) {
  echo $char;
}

In diesem Fall hat man also gleich zwei Vorteile: Foreach- und UTF-8-Unterstützung.

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.