2008-11-28 6 views
8

Gibt es eine einfache Möglichkeit, die HTTP_ACCEPT_LANGUAGE des Benutzers zu analysieren und das Gebietsschema in PHP zu setzen?Wie stelle ich das Gebietsschema eines Benutzers in PHP automatisch ein?

Ich weiß, dass das Zend-Framework eine Methode dafür hat, aber ich würde lieber nicht das gesamte Framework installieren, nur um diese ein bisschen Funktionalität zu verwenden.

Das Paket PEAR I18Nv2 befindet sich in der Betaversion und wurde seit fast drei Jahren nicht mehr geändert, daher möchte ich es lieber nicht verwenden.

Auch wäre es schön, wenn es herausfinden könnte, ob der Server unter Windows lief oder nicht, da Windows Gebietsschemastrings sich vom Rest der Welt unterscheiden ... (Deutsch ist "deu" oder "deutsch" statt "de".)

Antwort

2

Schöne Lösung ist on its way.

Ohne dass Sie diese Header analysieren müssen. Es ist eine durch Kommas getrennte Liste von Semikolon-getrennten Gebietsschemas und Attributen.

Es kann wie folgt aussehen:

en_US, en;q=0.8, fr_CA;q=0.2, *;q=0.1 

und dann jede locale versuchen, bis setlocale() sie akzeptiert. Bereite dich darauf vor, dass keiner von ihnen zusammenpasst.

Basieren Sie nicht darauf, etwas zu wichtig oder erlauben Sie Benutzern, es zu überschreiben, weil einige Benutzer falsch konfigurierte Browser haben.


Für Windows Gebietsschema, müssen Sie möglicherweise ISO 639-1 Namen zu ISO 639-2/3 konvertieren?

5

Es ist nicht so einfach wie es sein sollte (meiner bescheidenen Meinung nach). Zuerst müssen Sie die Locales aus dem $_SERVER['HTTP_ACCEPT_LANGUAGE'] extrahieren und sie nach ihren q Werten sortieren. Anschließend müssen Sie für jedes der gegebenen Gebietsschemas das entsprechende Gebietsschema des Systems abrufen, was auf einem * nix-Rechner kein Problem sein sollte (Sie müssen nur mit dem korrekten Zeichensatz zurechtkommen), aber unter Windows müssen Sie die Gebietsschemas in übersetzen Windows-Ländereinstellungen, z de_DE wird German_Germany sein (wieder müssen Sie auch mit Zeichensatzproblemen fertig werden, wenn Sie UTF-8 zum Beispiel in Ihrer App verwenden). Ich denke, Sie müssen eine Nachschlagetabelle für dieses Problem erstellen - und es gibt viele Locales ;-)

Nein, Sie versuchen ein Gebietsschema nach dem anderen (mit absteigenden q Werte sortiert), bis Sie eine Übereinstimmung mit finden setlocale() (Die Funktion gibt false zurück, wenn das angegebene Gebietsschema nicht festgelegt werden konnte).

Aber dann wird es ein letztes Hindernis zu bewältigen:

Die Locale-Informationen beibehalten werden pro Prozess, nicht pro Thread. Wenn Sie PHP auf einem multithreaded Server api wie IIS oder Apache auf Windows ausgeführt werden, können Sie plötzlich Änderungen der lokalen Einstellungen auftreten, während ein Skript wird, obwohl das Skript ausgeführt selbst nie genannt setlocale() selbst. Dies geschieht aufgrund anderer Skripts, die in verschiedenen Threads desselben Prozesses zur gleichen Zeit ausgeführt werden Ändern der systemweiten Gebietsschema mithilfe von setlocale().

(siehe: http://de2.php.net/manual/en/function.setlocale.php)

Dies bedeutet, dass Sie während der Ausführung eines Skripts plötzlichen locale Veränderungen erfahren können, weil ein anderer Benutzer mit einem anderen Gebietsschema nur Ihre Webseite getroffen.

Deshalb ist die erwähnte Zend_Locale beruht nicht auf der PHP-Funktion setlocale() (es nur benutzt, um das Systemgebietsschema Informationen abzurufen), sondern verwendet ein System auf der Grundlage der von der Unicode CLDR Project zur Verfügung gestellten Daten. Dies macht die Komponente unabhängig von all diesen setlocale() Problemen, aber dies führt auch zu einigen anderen Mängeln, wie zum Beispiel der fehlenden Unterstützung für lokalisierungsbewußte Zeichenfolgenoperationen (Sortieren zum Beispiel).

2

Ich weiß, dass das Zend Framework dies ein Verfahren zu tun hat, aber ich möchte lieber nicht den ganzen Rahmen installieren nur, dass ein Bit-Funktionalität zu nutzen.

Die gute Nachricht über Zend ist, dass Sie nicht alles installieren müssen. Es ist ein lose gekoppeltes Framework und du kannst einfach Zend_Locale verwenden, ohne eine der anderen Komponenten zu verwenden. Vielleicht möchtest du es mit Zend_Translate kombinieren.

Check it out

1

Es gibt http_negotiate_language, aber es hängt von der http-Erweiterung. Alternativ können Sie die Kommentare auf der Manualpage für eine Benutzerland-Implementierung lesen.