EinführungZend_Locale ist die Antwort des Frameworks auf die Frage "Wie kann dieselbe Anwendung auf der ganzen Welt verwendet werden?". Die meisten Leute werden sagen "Das ist einfach. Lasst uns alle Ausgaben in die unterschiedlichsten Sprachen übersetzen". Aber eine einfache Übersetzungstabelle, die Phrasen von einer Sprache in die andere übersetzt, ist nicht genug. Verschiedene Regionen haben auch unterschiedliche Regeln für Vornamen, Nachnamen, Titel, Format von Nummern, Daten, Zeiten, Währungen usw. Was wir benötigen ist » Lokalisierung und die vergleichbare Internationalisierung. Beide werden oft abgekürzt zu L10n und I18n. Internationalisierung bezeichnet mehr die Benutzung von Systemen für die spezielle Benutzung durch eindeutige Gruppen wie zum Beispiel Sprachübersetzung, Unterstützung von lokalen Konventionen für Plurale, Daten, Zeiten, Währungen, Namen, Symbolen, Sortierungen, Reihungen und viele mehr. L10n und I18n sind einander sehr ähnlich. Zend Framework bietet Unterstützung für diese Konventionen durch eine Kombination von Komponenten wie Zend_Locale, Zend_Date, Zend_Measure, Zend_Translate, Zend_Currency und Zend_TimeSync. Tip
Zend_Locale und setLocale()Die » Dokumentation von PHP sagt, dass setlocale() nicht threadsicher ist, weil es pro Prozess behandelt wird und nicht pro Thread. Das bedeutet, dass man in multithreaded Umgebungen das Problem bekommen kann, dass sich das Gebietsschema (Locale) ändert, während das Skript diese Änderung nie selbst durchgeführt hat. Deswegen kann es zu unerwarteten Ergebnissen kommen, wenn man setLocale() in seinen Skripts verwendet. Wenn Zend_Locale verwendet wird, hat man diese Einschränkungen nicht, da Zend_Locale weder von PHPs setlocale() abhängig ist, noch irgendwie mit ihr gekoppelt ist. Was ist LokalisierungLokalisierung bedeutet, dass eine Anwendung (oder Homepage) von verschiedenen Benutzern verwendet werden kann, die unterschiedliche Sprachen sprechen. Aber wie bereits angedeutet, heißt Lokalisierung mehr als nur die Übersetzung von Zeichenketten. Es beinhaltet
Was ist ein Gebietsschema?Jeder Computer benutzt Gebietsschemata, selbst wenn Sie es nicht wissen. Anwendungen, welche keine Unterstützung für Lokalisierung bieten, unterstützen zumindest genau ein Gebietsschema (das Gebietsschema des Authors). Wenn eine Klasse oder Funktion Lokalisierung verwendet, sagen wir, sie ist lokalisierbar. Aber wie weiß der Code, welches Gebietsschema ein Benutzer erwartet ? Eine Gebietsschema Zeichenkette oder Objekt, welches ein unterstütztes Gebietsschema identifiziert, gibt Zend_Locale und dessen Unterklassen Zugriff auf Informationen über die Sprache und Region, welche der Benutzer erwartet. Formatierungen, Normalisierungen und Konvertierungen werden anhand dieser Informationen durchgeführt. Wodurch werden Gebietsschemata repräsentiert?Eine Gebietsschema-Zeichenkette besteht aus Informationen über die Sprache des Benutzers und die bevorzugte/primäre geographische Region (z.B. Staat oder Region von seinem Zuhause oder Arbeitsplatz). Die Gebietsschema Zeichenkette, welche im Zend Framework benutzt werden, sind international definierte Standardabkürzungen von Sprachen und Regionen. Sie werden geschrieben als sprache_REGION. Beide Teile, sowohl Sprache als auch Region, werden mit Buchstaben, ASCII-Zeichen, abgekürzt.
Ein Benutzer aus den USA würde die Sprache Englisch und die Region USA erwarten, beschrieben durch das Gebietsschema "en_US". Ein Benutzer aus Deutschland würde die Sprache Deutsch und die Region Deutschland erwarten, beschrieben durch das Gebietsschema "de_DE". Hier findest Du eine » Liste von vordefinierten Sprachen und Kombinationen von Regionen wenn ein bestimmtes Gebietsschema im Zend Framework ausgewählt werden muß. Example #1 Auswählen eines speziellen Gebietsschemas
Ein deutscher Benutzer in Amerika würde die Sprache Deutsch und die Region USA erwarten, aber diese nicht-standardmäßigen Mischungen werden nicht direkt als "Gebietsschema" unterstützt und erkannt. Wird eine ungültige Kombination benutzt, dann wird sie stattdessen automatisch gekürzt, indem die Region entfernt wird. Zum Beispiel würde "de_IS" zu "de" und "xh_RU" zu "xh" gekürzt werden, weil keine dieser Kombinationen gültig ist. Wenn die Sprache nicht unterstützt wird (z.B. "zz_US") oder diese nicht existiert, dann wird zusätzlich ein Standard "root" Gebietsschema benutzt. Dieses "root" Gebietsschema hat Standarddefinitionen für international bekannte Repräsentationen von Daten, Zeiten, Nummern, Währungen usw. Der Prozess der Kürzung hängt von der gewünschten Information ab, weil einige Kombinationen von Sprache und Region für eine gewisse Art von Informationen gültig sind (z.B. Daten) aber für andere nicht (z.B. Währungsformate). Achtung vor historischen Änderungen oder dem Versuch, die verschiedenen Änderungen der Zeitzonen zu verfolgen, die im Laufe der langen Zeit in den vielen Regionen gemacht wurden, da Zend Framework Komponenten darüber nichts wissen kann. Zum Beispiel kann » hier eine historische Liste mit Dutzenden Änderungen von Regierungen angesehen werden und ob eine Region DST (Sommer-/Winterzeit) unterstützt und sogar in welche Zeitzone eine bestimmte geographische Region gehört. Das bedeutet, wenn Datumsberechnungen gemacht werden, wird die Berechnung, welche durch die Zend Framework Komponenten durchgeführt wird, nicht an diese Änderungen angepasst. Stattdessen wird die korrekte Uhrzeit benutzt, welche für die aktuell benutzte Zeitzone angegeben wurde, wobei moderne Regeln für Sommer-/Winterzeit und Zeitzonenzuordnung anhand von geographischen Regionen verwendet werden. Auswahl des richtigen GebietsschemasIn den meisten Situationen wird new Zend_Locale() automatisch das richtige Gebietsschema auswählen, wobei die Informationen benutzt werden, welche der Webbrowser des Benutzers zur Verfügung stellt. Wenn statt dessen new Zend_Locale(Zend_Locale::ENVIRONMENT benutzt wird, dann werden die Informationen vom Betriebsystem des hostenden Servers, dafür verwendet, wie anbei beschrieben. Example #2 Automatische Auswahl des Gebietsschemas
Der Suchalgorithmus, welcher von Zend_Locale für die automatische Auswahl des Gebietsschemas verwendet wird, verwendet drei Informationsquellen:
Verwenden automatischer GebietsschemataZend_Locale bietet drei zusätzliche Gebietsschemata. Diese Gebietsschemata gehören zu keiner Sprache oder Region. Es sind "automatische" Gebietsschemata, was bedeutet dass sie den gleichen Effekt haben wie die Methode getDefault(), aber ohne die negativen Effekte wie die Erstellung einer Instanz. Diese "automatischen" Gebietsschemata können überall verwendet werden, wo auch Standard-Gebietsschemata verwendet werden können, und für die Definition eines Gebietsschemas, kann auch die String-Repräsentation verwendet werden. Das bietet Einfachheit für Situationen, wo mit Gebietsschemas gearbeitet wird, die vom Browser geliefert werden. Es gibt drei Gebietsschemata mit leicht unterschiedlichem Verhalten:
Example #3 Verwenden automatischer Gebietsschemata
Verwenden eines StandardgebietsschemasIn einigen Umgebungen ist es nicht möglich automatisch ein Gebietsschema zu erkennen. Man kann dieses Verhalten zum Beispiel sehen, wenn eine Anfrage von der Kommandozeile kommt, oder der anfragende Browser kein Sprachtag gesetzt hat und zusätzlich der Server das Standardgebietsschema 'C' gesetzt hat oder ein anderes propäritäres Gebietsschema. In solchen Fällen wirft Zend_Locale normalerweise eine Ausnahme mit einer Nachricht, dass die automatische Erkennung des Gebietsschemas nicht erfolgreich war. Es gibt zwei Optionen um diese Situation handzuhaben. Entweder durch das Setzen eines neuen Gebietsschemas per Hand, oder der Definition eines Standardgebietsschemas. Example #4 Handhabung von Ausnahmen für Gebietsschemas
Aber das hat einen großen negativen Effekt. Man muß das Gebietsschema-Objekt in jeder Klasse setzen, die Zend_Locale verwendet. Das kann sehr unhandlch sein, wenn mehrere Klassen verwendet werden. Seit Zend Framework Release 1.5 gibt es einen viel besseren Weg um das handzuhaben. Man kann ein Standardgebietsschema mit der statischen setDefault() Methode setzen. Natürlich wird jedes unbekannte oder nicht voll qualifizierte Gebietsschema eine Ausnahme werfen. setDefault() sollte der erste Aufruf sein, bevor irgendeine Klasse initiiert wird, die Zend_Locale verwendet. Siehe das folgende Beispiel für Details: Example #5 Setzen eines Standardgebietsschemas
Für den Fall, dass kein Gebietsschema erkannt wird, wird automatisch das Gebietsschema de verwendet. Andernfalls wird das erkannte Gebietsschema verwendet. ZF lokalisierbare KlassenIm Zend Framework sind lokalisierbare Klassen von Zend_Locale abhängig, um ein Gebietsschema automatisch auszuwählen, wie im oberen Abschnitt geschrieben. Das Erstellen eines Datums durch Verwendung von Zend_Date ohne die Angabe eines Gebietsschemas führt als Ergebnis zu einem Objekt mit einem Gebietsschema, basierend auf den Informationen, welche durch den Webbrowser des Benutzers zur Verfügung gestellt werden. Example #6 Daten verwenden das aktuelle Gebietsschema des Web Benutzers
Um dieses Standardverhalten zu übergehen, und eine lokalisierbare Zend Framework Komponente dazu zu bringen ein spezielles Gebietsschema zu benutzen, welches unabhängig vom Gebietsschema des Besucher der Webseite ist, muß als dritter Parameter im Konstruktor das Gebietsschema angegeben werden. Example #7 Übergehen der Auswahl des standardmäßigen Gebietsschemas
Wenn viele Objekte benutzt werden, die alle das gleiche Gebietsschema verwenden, sollte das Gebietsschema explizit definiert werden, um die zusätzliche Arbeit jedes Objekts durch die Bestimmung des standardmäßigen Gebietsschemas zu verringern. Example #8 Optimierung der Geschwindigkeit durch Benutzung eines Standard-Gebietsschemas
Anwendungsweites GebietsschemaZend Framework erlaubt die Verwendung eines anwendungsweiten Gebietsschemas. Man kann einfach eine Instanz von Zend_Locale in der Registry mit dem Schüssel 'Zend_Locale' setzen. Dann wird diese Instanz in allen Klassen des Zend Framework verwendet, die Gebietsschemata verwenden. Auf diesem Weg wird eine Instanz in der Registry gesetzt und man kann dann das weitere Setzen vergessen. Sie wird automatisch in allen anderen Klassen verwendet. Siehe das folgende Beispiel für die richtige Verwendung: Example #9 Verwendung eines anwendungsweiten Gebietsschemas
Zend_Locale_Format::setOptions(array $options)Die Option 'precision' wird benutzt, um einen Wert zu verkürzen oder mit extra Ziffern zu strecken. Ein Wert von '-1' verhindert die Veränderung der Anzahl an Ziffern im Nachkommateil des Wertes. Die Option 'locale' hilft, wenn Nummern und Daten analysiert werden und hierbei Trennzeichen oder Monatsnamen verwendet werden. Die Datumsformat Option 'format_type' wählt zwischen CLDR/ISO Datumsdefinitionen und PHPs date() Definitionen. Die Option 'fix_date' erlaubt oder verhindert eine Automatik welche versucht falsche Daten zu korrigieren. Die Option 'number_format' definiert ein Standardformat für Nummern bei Verwendung der Funktion toNumber(). (siehe diesen Abschnitt ). Die Option 'date_format' kann verwendet werden um ein Standarddatumsformat zu definieren. Aber Achtung bei der Verwendung von getDate(), checkDateFormat() und getTime() nach der Verwendung von setOptions() mit einem 'date_format'. Um diese vier Methoden mit einem Standard Datumsformat für ein Gebietsschema zu benutzen, muß array('date_format' => null, 'locale' => $locale) in deren Optionen angegeben werden. Example #10 Daten die das richtige Gebietsschema des Web Benutzers verwenden
Um mit den Standarddefinitionen eines Gebietsschemas zu arbeiten kann die Konstante Zend_Locale_Format::STANDARD verwendet werden. Das Setzen der Konstante Zend_Locale_Format::STANDARD für date_format benutzt die Standarddefinition des aktuellen Gebietsschemas. Das Setzen für number_format benutzt das Standard Nummernformat dieses Gebietsschemas. Und das Setzen für 'locale' verwendet das Standard Gebietsschema des Servers oder Browsers. Example #11 Verwendung von STANDARD-Definitionen für setOptions()
Zend_Locale und dessen Subklassen beschleunigenZend_Locale und dessen Subklassen können durch die Verwendung von Zend_Cache beschleunigt werden. Man sollte die statische Methode Zend_Locale::setCache($cache) verwenden, wenn man Zend_Locale benutzt. Zend_Locale_Format kann schneller gemacht werden, indem die Option cache innerhalb von Zend_Locale_Format::setOptions(array('cache' => $adapter)); aufgerufen wird. Wenn beide Klassen verwendet werden, sollte nur für Zend_Locale ein Cache gesetzt werden, da der zuletzt gesetzte Cache den vorher gesetzten Cache überschreibt. Der Bequemlichkeit halber gibt es auch die statischen Methoden getCache(), hasCache(), clearCache() und removeCache(). Wenn kein Cache gesetzt wird, dann setzt Zend_Locale automatisch von selbst einen Cache. Manchmal ist es gewünscht zu verhindern, dass ein Cache gesetzt wird, selbst wenn das die Performance verringert. In diesem Fall sollte die statische Methode disableCache(true) verwendet werden. Sie schaltet nicht nur den aktuell gesetzten Cache aus, ohne ihn zu löschen, sondern verhindert auch, dass ein Cache automatisch erstellt wird, wenn kein Cache gesetzt ist.
|