Sven Rautenberg: UTF-8 String mit strtr() filtern

Beitrag lesen

Moin!

PHP ist generell (noch) nicht dafür ausgelegt, Mehrbyte-Kodierungen zu verarbeiten. Mehrbyte-Kodierungen können derzeit nur mit der Multibyte-String-Extension bearbeitet werden und einigen ausgewählten Funktionen, denen üblicherweise explizit die von ISO-8859-1 abweichende Kodierung mitgeteilt werden muss.

Also würde ich dir doch mal spontan widersprechen: PHP _IST_ dafür ausgelegt, Mehrbyte-Kodierungen zu verarbeiten. Denn die mb-Extension macht ja genau das.

Allerdings erlaubt es PHP derzeit nicht, Mehrbyte-Kodierungen TRANSPARENT mit den regulären Stringfunktionen zu bearbeiten (außer man aktiviert das Overloading - halte ich aber eher für ungeeignet).

Unter dem Strich ist man mit PHP dadurch eigentlich in einer gemischten Lage: Auf der einen Seite ist man in der Lage, je nach Wunsch sowohl auf Basis von Bytes oder von Zeichen zu arbeiten, indem man eben mb_*-Funktionen oder normale "String"-Funktionen verwendet. Auf der anderen Seite muss man sich eben genau dieser Unterscheidung immer bewußt sein, und es gibt halt nicht für jede String-Funktion eine identische mb-Funktion.

Insgesamt darf man den Zustand der Codierungsmöglichkeiten in PHP durchaus als chaotisch bezeichnen, weil sich die diversen Extensions bzw. Funktionsgruppen hinsichtlich der Kodierung ihr eigenes Süppchen gekocht haben im Laufe der Zeit. Einige arbeiten im ASCII-/ISO-8859-1-Raum, einige arbeiten mit UTF-8-Kodierung, einige erlauben einen Kodierungsparameter.

Auf der anderen Seite ist festzustellen, dass PHP mit UTF-8 sehr gut umgehen kann, wenn man gewisse Dinge beachtet. Und weil diese Dinge immer gleichartig zu beachten sind, lernt man im Laufe der Zeit, sie automatisch korrekt anzuwenden - ungefähr so, wie die Anwendung der korrekten Prüfung mit strpos() auf Abwesenheit des gesuchten Strings vs. Fundstelle an Position 0 im String.

Als PHP-Verwender muss man die Existenz dieser Funktionen und Parameter kennen, wenn man mit Mehrbyte-Kodierungen arbeiten möchte.

Eben. Und PHP wird im Zweifel den String einfach fehlkodiert weiterreichen und das Problem dann dem Programmierer oder dem Anwender aufhalsen.

Ich kenne ein Negativ-Beispiel aus Python. Der Spamfilter für Trac ist offensichtlich von einem Programmierer aus der ASCII-Welt geschrieben worden. Wenn ein User Texte mit Umlauten postet, dann steigt der Spamfilter mit einem Kodierungsfehler aus, und der Spam-Score ist 0. Mit ASCII-Zeichen allein funktioniert es. Dieses eigenmächtige Fehlerwerfen von Python, welches nur im UTF-8-Fall auftritt (über die Problematik, die Kodierung eines Textes immanent zu erkennen, brauchen wir nicht diskutieren), halte ich für deutlich problematischer, als das in PHP anzunehmende Verhalten, an dieser Stelle einfach den Spam-Text mit "merkwürdigen Zeichen" zu durchforsten und eben gerade NICHT auszusteigen.

Mit anderen Worten: Kodierungsprobleme kann man sich in JEDER Sprache einhandeln, wenn man die Regeln nicht kennt und nicht darauf achtet. Jede Applikation hat dafür zu sorgen, dass sie die hereinkommenden Zeichenketten mit der verwendeten Kodierung taggt und (noch nicht bei PHP) im Bedarfsfall on-the-fly umkodiert, wenn die Ausgabe eine andere Kodierung verlangt. Dies geschieht entweder durch eine entsprechende Angabe der Datenquelle selbst (HTTP-Header, Meta-Tags in HTML), bei Fehlen derselben muss die Kodierung halt explizit im Programm definiert werden. Ohne solch eine Angabe sollte im Prinzip jede Software sofort anhalten und die fehlende Kodierungsdefinition bemängeln.

Aber wir wünschen uns ja auch schon seit zwanzig Jahren Browser, die bei fehlerhaftem, invalidem HTML aussteigen und den Fehler monieren...

- Sven Rautenberg