It's not as easy as it should be (in my humble opinion). First of all you have to extract the locales from the $_SERVER['HTTP_ACCEPT_LANGUAGE']
and sort them by their q
values. Afterwards you have to retrieve the appropriate system locale for each of the given locales, which should be no problem on a *nix machine (you only might have to cope with the correct charset) but on Windows you'll have to translate the locales into Windows locales, e.g. de_DE
will be German_Germany
(again you also have to cope with charset issues if you're using UTF-8 in your app for example). I think you'll have to build a lookup table for this issue - and there are a lot of locales ;-)
No you try one locale after the other (sorted with descending q
values) until you find a match using setlocale()
(the function will return false
if the given locale could not be set).
But then there will be a last obstacle to cope with:
The locale information is maintained
per process, not per thread. If you
are running PHP on a multithreaded
server api like IIS or Apache on
Windows you may experience sudden
changes of locale settings while a
script is running although the script
itself never called setlocale()
itself. This happens due to other
scripts running in different threads
of the same process at the same time
changing the processwide locale using
setlocale().
(see: http://de2.php.net/manual/en/function.setlocale.php)
This means that you could experience sudden locale changes during the execution of a script because another user with a different locale set just hit your webpage.
Therefore the mentioned Zend_Locale
does not rely on the PHP function setlocale()
(it's only used to retrieve the system locale information) but instead uses a system based on the data provided by the Unicode CLDR Project. This makes the component independent from all those setlocale()
issues but this also introduces some other deficiencies such as the lack of support for locale-aware string operations (sorting for example).