22.052013

Internationalisierung mit PHP Intl - Teil 2

Heute geht es weiter mit der Internationalisierung mit der PHP Erweiterung Intl. Vor wenigen Wochen habe ich bereits die NumberFormatter-Klasse und die IntlDateFormatter-Klasse vorgestellt, die sich beide als sehr nützlich erwiesen.

Collator

Das Sortieren von Strings ist schon in rein deutschen Anwendungen manchmal mit Fehlern verbunden. Wenn man nicht darauf achtet, landen zum Beispiel Umlaute am Ende der Sortierung. Dazu kommt, dass es in vielen Sprachen, die das lateinische Alphabet um Umlaute (im deutschen ä, ö, ü und ß) erweitern, verschieden Arten gibt, diese einzusortieren. Im Deutschen kann man die zusätzlichen Buchstaben auf vier Arten einsortieren:

  • Man behandelt die Umlaute, als seien sie ohne Punkte. Ä wird dann wie A behandelt. Müll und Mull würden also an die gleiche Stelle einsortiert werden.
  • Gleichordnung von Grundbuchstaben, Doppelbuchstaben und Umlaut, wenn Doppelbuchstabe wie Umlaut gesprochen wird. Muell wird wie Müll oder Mull sortiert. Duell dagegen zwischen Duden und Dugast.
  • Man löst den Umlauf auf. Aus ä wird dann ae. Müll wird wie Muell sortiert.
  • Man separiert die Umlaute als selbständige Buchstaben.

Umlaute gelten in vielen Ländern (im Gegensatz zu Deutschland) als eigene Buchstaben und werden meistens ganz ans Ende einsortiert. Hier einige Beispiele für Regelungen in anderen Ländern:

Schwedische Sortierung

  • å kommt nach z
  • ä kommt nach å
  • ö kommt nach ä
  • ü und y sind gleich

Britische Sortierung

  • ä kommt nach a
  • ö kommt nach o
  • ü kommt nach u
  • ß kommt nach s
  • Mc wird wie Mac behandelt

Wenn man jetzt mit PHP die Sortierung Landesspezifisch vornehmen möchte muss man sich zu erst ein Collator Objekt erstellen. Anschließend übergibt man der sort-Funktion des Collators ein Array mit den zu sortierenden Einträgen:

$list = array('Muff', 'Müll', 'Mull', 'Ärzte', 'Arzt', 'Mund', 'MySQL');
sort($list); // Normale PHP Sortierung
print_r($list); // Array ( [0] => Arzt [1] => Muff [2] => Mull [3] => Mund [4] => MySQL [5] => Müll [6] => Ärzte )
$collDE = Collator::create('de_DE'); // Deutsche Sortierung
$collDE->sort($list);
print_r($list); // Array ( [0] => Arzt [1] => Ärzte [2] => Muff [3] => Mull [4] => Müll [5] => Mund [6] => MySQL )
$collSE = Collator::create('sv_SE'); // Schwedische Sortierung
$collSE->sort($list);
print_r($list); // Array ( [0] => Arzt [1] => Muff [2] => Mull [3] => Mund [4] => Müll [5] => MySQL [6] => Ärzte )

Wie man schön sehen kann: Die Standard-PHP Funktion sort() sortiert alphabetisch, umlaute werden ans Ende gestellt. Mit dem Collator werden die Landesspezifischen Sortierungen verwendet, wie in Deutschland die Einsortierung der Umlaute bei den Buchstaben.
Die Collator-Klasse bietet noch einige weitere nützliche Funktionalität. So lassen sich mit der Funktion Collator::compare() zwei Strings vergleichen. Die Funktion Collator::asort() ist das äquivalent zur PHP-Standard-Funktion asort(). Und mit Collator::setStrength() kann man das Level der Vergleiche einstellen.

Locale

Die Locale-Klasse beinhaltet eine ganze Sammlung nützlicher Funktionen für die Bestimmung und Anzeige der Sprache und der Region eines Benutzers. Um die bevorzugte Sprache des Benutzers aus den Browsereinstellungen auszulesen kann man die Funktion acceptFromHttp() verwenden:

$locale = Locale::acceptFromHttp($_SERVER['HTTP_ACCEPT_LANGUAGE']);
echo $locale; // Gibt beispielsweise de_DE, de_AT oder en_US aus

Mit getDisplayRegion() und getDisplayLanguage() kann man sich Sprachen und Länder in fast jeder beliebigen Sprache ausgeben lassen! Beide Funktionen bekommen einen Parameter mit einem Locale übergeben. Optional kann man einen zweiten Parameter angeben, der eine Übersetzung vornimmt, sonst wird die Sprache bzw. die Region standardmäßig auf englisch ausgegeben.

echo Locale::getDisplayLanguage('de_DE', 'de_DE'); // Deutsch
echo Locale::getDisplayLanguage('de_DE'); // German
echo Locale::getDisplayLanguage('de_DE', 'fr_FR'); // allemand
echo Locale::getDisplayLanguage('de_DE', 'pl_PL'); // niemiecki
echo Locale::getDisplayRegion('pl_PL', 'de_DE'); // Polen
echo Locale::getDisplayRegion('pl_PL'); // Poland
echo Locale::getDisplayRegion('pl_PL', 'fr_FR'); // Pologne
echo Locale::getDisplayRegion('pl_PL', 'pl_PL'); // Polska

Dies war der zweite Teil meiner "Internationalisierung mit PHP Intl"-Reihe. Den nächsten Teil gibt es in ein paar Wochen.