10.042013

Internationalisierung mit PHP Intl

Die PHP Intl Erweiterung die seit PHP 5.3.0 standardmäßig im Funktionsumfang enthalten ist (und seit Version 5.2.0 nachinstalliert werden kann) erfreut sich steigender Beliebtheit. Nach wie vor wird sie aber immer noch relativ selten verwendet. Nicht zuletzt wegen der sehr spärlich ausformulierten Dokumentation. In diesem Blogeintrag möchte ich die Intl Erweiterung vorstellen und die Vorteile aufzeigen.

Installation

In allen PHP Versionen die derzeit unterstützt werden ist die Intl Erweiterung bereits installiert. Wenn ihr phpinfo() aufruft sollte es einen intl Eintrag geben (siehe Abbildung). Sollte Intl aus welchen Gründen auch immer nicht installiert sein, müsst ihr es nachinstallieren. Bei Ubuntu geht das zum Beispiel mit dem Befehl

apt-get install php5-intl

Danach muss PHP neu gestartet werden und der Aufruf von phpinfo() sollte die Intl Erweiterung anzeigen.

intl

NumberFormatter

Ein Problem bei der Internationalisierung sind Zahlen. Zahlen werden von Region zu Region unterschiedlich dargestellt. Beispiele:

  • 9 876 543,21 in Frankreich
  • 9.876.543,21 in Deutschland
  • 9,876,543.21 in dem USA

Dieses Problem können wir jetzt ganz einfach lösen. Wir lassen die Zahlen vom NumberFormatter formatieren. Das sieht in der Praxis dann zum Beispiel so aus (alle Funktionen der Intl Erweiterung sind sowohl objektorientiert als auch Funktional aufrufbar. Ich verwende in meinen Beispielen die objektorientierte Variante):

$f1 = new NumberFormatter("de-DE", NumberFormatter::DECIMAL);
 echo $f1->format(9876543.21); // 9.876.543,21
$f2 = new NumberFormatter("fr-FR", NumberFormatter::DECIMAL);
 echo $f2->format(9876543.21); // 9 876 543,21
$f3 = new NumberFormatter("en-US", NumberFormatter::DECIMAL);
 echo $f3->format(9876543.21); // 9,876,543.21

Der Konstruktor bekommt einen String mit einem Locale übergeben, eine Konstante für die Art der Formatierung und optional noch einen String mit einem Pattern. Dabei kann er viele vordefinierte Konstanten unterscheiden. Im Beispiel oben wurde NumberFormatter::DECIMAL gewählt für Dezimalzahlen. Eine komplette Liste findet sich hier. Damit deckt der NumberFormatter bereits eine ganze Palette an Formatierungen ab. Möchte man beispielsweise eine Zahl in ausgeschriebener Form darstellen genügt folgender Code:

$f4 = new NumberFormatter("de-DE", NumberFormatter::SPELLOUT);
 echo $f4->format(876543);
 // achthundertsechsundsiebzigtausendfünfhundertdreiundvierzig
$f5 = new NumberFormatter("en-US", NumberFormatter::SPELLOUT);
 echo $f5->format(876543);
 // eight hundred and seventy-six thousand, five hundred and forty-three

IntlDateFormatter

Ein ganz ähnliches Problem wie die Darstellung von Zahlen ist die Formatierung von Datumsangaben. Das in Deutschland übliche Format "DD.MM.YYYY" ist im internationalen Vergleich eher unbekannt. Die US-Amerikaner bevorzugen zum Beispiel die Darstellung "MM/TT/YY". Der Standard ISO 8601 empfiehlt für Daten das Format "YYYY-MM-DD". Dieses wird auch oft als "internationales Datumsformat" bezeichnet.

Mit PHP Intl können wir nun ähnlich einfach wie die Formatierung für Zahlen auch Formatierungen für Datumsangaben (und Uhrzeiten) vornehmen. Der Konstruktor des IntlDateFormatter bekommt das gewünschte Locale übergeben und zwei Konstanten. Die Erste steht für die Formatierung des Datums, die Zweite für die Formatierung der Uhrzeit. Das ganze sieht dann zum Beispiel so aus:

$f6 = new IntlDateFormatter("de-DE", IntlDateFormatter::SHORT, IntlDateFormatter::NONE);
 echo $f6->format(1363683173); // 19.03.13
$f7 = new IntlDateFormatter("en-US", IntlDateFormatter::SHORT, IntlDateFormatter::NONE);
 echo $f7->format(1363683173); // 3/19/13
$f8 = new IntlDateFormatter("fr-FR", IntlDateFormatter::SHORT, IntlDateFormatter::NONE);
 echo $f8->format(1363683173); // 19/03/13

Hier wurde jetzt als Datenformat "SHORT" gewählt. Es gibt aber auch noch "MEDIUM", "LONG" und "FULL". Der IntlDateFormatter ist ein sehr mächtiges Werkzeug für die Internationalisierung. Neben diesen einfachen Formatierungen kann er auch Wochentage in allen Sprachen ausgeben und kann mit Zeitzonen umgehen.

Dies war der erste Teil einer Reihe von Blogeinträgen zum Thema Internationalisierung mit PHP Intl. Den nächsten Teil werde ich in wenigen Wochen veröffentlichen.