Wie kann ich automatisch ein Gebietsschema des Benutzers in PHP?
-
11-07-2019 - |
Frage
Gibt es eine einfache Art und Weise des Benutzers HTTP_ACCEPT_LANGUAGE und legen Sie das Gebietsschema in PHP?
zu analysierenIch weiß, dass das Zend Framework eine Methode, dies zu tun, aber ich möchte lieber nicht den ganzen Rahmen installieren Sie einfach zu bedienen, dass ein Bit-Funktionalität.
Das PEAR I18Nv2 Paket ist in der Betaphase und ist seit fast drei Jahren nicht geändert, so dass ich lieber nicht verwenden, wenn möglich.
Auch schön wäre, wenn es herausfinden könnte, wenn der Server unter Windows oder nicht ausgeführt wurde, da locale Strings Windows unterscheidet sie von dem Rest der Welt ... (deutsch „deu“ oder „Deutsch“ ist statt " de“).
Lösung
Nizza Lösung auf dem Weg .
Ohne dass Sie benötigen diesen Header zu analysieren. Es ist eine durch Kommata getrennte Liste von Semikolon getrennten locales und Attributen.
Es kann wie folgt aussehen:
en_US, en;q=0.8, fr_CA;q=0.2, *;q=0.1
und versuchen Sie dann jede locale bis setlocale()
sie akzeptiert. Seien Sie darauf vorbereitet, dass keiner von ihnen überein.
Haben Basis nicht darauf etwas zu wichtig oder können Benutzer es außer Kraft zu setzen, da einige Benutzer falsch konfigurierte Browser haben.
Für Windows locale, vielleicht müssen Sie ISO 639-1 Namen zu ISO 639-2 / 3?
konvertierenAndere Tipps
Es ist nicht so einfach, wie es (in meiner bescheidenen Meinung nach) sein sollte. Zunächst einmal müssen Sie die Schauplätze aus dem $_SERVER['HTTP_ACCEPT_LANGUAGE']
extrahieren und sie durch ihre q
Werte sortieren. Danach Sie die entsprechende Systemgebietsschema für jede der gegebenen locales abrufen müssen, was aber kein Problem auf einem * nix-Maschine sein sollte (eventuell nur mit dem richtigen Zeichensatz zu bewältigen haben), aber unter Windows finden Sie die locales übersetzen müssen in Windows-Schauplätze, zB de_DE
wird German_Germany
werden (wieder müssen Sie auch mit charset Probleme bewältigen, wenn Sie UTF-8 in Ihrer App beispielsweise verwenden). Ich denke, dass es eine Lookup-Tabelle für dieses Problem bauen müssen - und es gibt eine Menge von Schauplätzen; -)
Nein versuchen Sie eine locale nach dem anderen (sortiert mit q
Werte absteigend), bis Sie eine Übereinstimmung finden mit setlocale()
(die Funktion kehrt false
, wenn die angegebene locale konnte nicht gesetzt werden).
Aber dann wird es ein letztes Hindernis zu bewältigen sein:
Die locale Information wird beibehalten pro Prozess, nicht pro Faden. Wenn du PHP auf einem multithreaded laufen Server api wie IIS oder Apache auf Windows Sie können plötzlich auftreten Änderungen der lokalen Einstellungen, während ein Skript ausgeführt wird, obwohl das Skript selbst nie setlocale () aufgerufen selbst. Dies geschieht aufgrund anderer Skripte in verschiedenen Threads ausgeführt des gleichen Prozesses zur gleichen Zeit Ändern des Process locale mit setlocale ().
(siehe: http://de2.php.net/manual/en /function.setlocale.php )
Das 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 der genannte Zend_Locale
beruht nicht auf der PHP-Funktion setlocale()
(es wird nur verwendet, um das System locale-Informationen abgerufen werden), sondern verwendet ein System auf der Grundlage der zur Verfügung gestellten Daten durch die Unicode CLDR Projekt . Dies macht die Komponente unabhängig von allen jenen setlocale()
Probleme, aber dies stellt auch einige andere Mängel wie die fehlende Unterstützung für locale-aware String-Operationen (Sortierung zum Beispiel).
Ich weiß, dass das Zend Framework eine Methode hat Um dies zu tun, aber ich möchte lieber nicht installieren der ganze Rahmen, dass nur zu verwenden, ein Bit-Funktionalität.
Die gute Nachricht über Zend ist, brauchen Sie nicht, um alles zu installieren. Es ist ein losely gekoppelt Rahmen und Sie können nur den Einsatz von Zend_Locale machen, ohne dass die anderen Komponenten. Vielleicht möchten Sie es mit Zend_Translate kombinieren.
Es gibt http_negotiate_language
, aber es hängt davon ab, die http-Erweiterung. Alternativ finden Sie die Kommentare auf der Hilfeseite für eine Userland-Implementierung.