3

I wanted to know, is there any way from PHP/javascript to get current client OS language. I tried to use $_SERVER["HTTP_ACCEPT_LANGUAGE"] but sometimes it get the wrong language. For example in Google Chrome:

  1. My OS: Windows 7
  2. Language: English

Using $_SERVER["HTTP_ACCEPT_LANGUAGE"] I got this result:

HTTP_ACCEPT_LANGUAGE: zh,en-US;q=0.8,en;q=0.6

It said "zh" is my primary language.

Is there any other way to get client OS language? Because that's what I wanted, not the browser language setting. Thanks

user430926
  • 4,017
  • 13
  • 53
  • 77
  • 2
    `zh` is because your browser has detected that you live in that country and hence you should recieve that language as your primary language. Chrome does this to help the users as much as possible (includes google search results, they will be based on a major city near you.. mine is Stockholm and i don't even live near.. and yes i'm well awware that it's a lot of geo-detection on a IP/Hostname basis but that's the baseline of the functionality) – Torxed May 07 '13 at 13:16
  • 3
    *It said "zh" is my primary language.* — No, it doesn't. Since `zh` doesn't have an explicit quality value, it has a quality of `1.0`. This is the same quality as `en-US`, therefore `zh` and `en-US` have equal weights. – Quentin May 07 '13 at 13:17
  • @Quentin is right. Perhaps you could get something from user agent string. – Tasso Evangelista May 07 '13 at 13:19
  • HTTP_USER_AGENT: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31, doesn't help much. But if zh,en-US;q=0.8 have equal weights it's difficult to choose. Since I wanted to get client OS language not the browser language setting is there any other way? – user430926 May 08 '13 at 02:25

3 Answers3

4

try this function

function getUserLanguage() {
 $langs = array();
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
// break up string into pieces (languages and q factors)
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
$_SERVER['HTTP_ACCEPT_LANGUAGE'], $lang_parse);
if (count($lang_parse[1])) {
// create a list like â??enâ?? => 0.8
$langs = array_combine($lang_parse[1], $lang_parse[4]);
// set default to 1 for any without q factor
foreach ($langs as $lang => $val) {
if ($val === '') $langs[$lang] = 1;
}
// sort list based on value
arsort($langs, SORT_NUMERIC);
}
}
//extract most important (first)
foreach ($langs as $lang => $val) { break; }
//if complex language simplify it
if (stristr($lang,"-")) {$tmp = explode("-",$lang); $lang = $tmp[0]; }
return $lang;
}
Ajay Patel
  • 791
  • 11
  • 24
2

Send it via javascript on IE?

  • navigator.browserLanguage: browser language
  • navigator.systemLanguage: Windows system language
  • navigator.userLanguage: Windows user-specific language

Thanks to: Is there anyway to detect OS language using javascript?

That's the only way besides the one you've mentioned to get the language of the client OS, PHP is run by the server and nothing else.

Build a PHP sorting function.

HTTP_ACCEPT_LANGUAGE: zh,en-US;q=0.8,en;q=0.6

zh and en-US share the same q= value, meaning that you can sort on the highest language value and default to en-US if the quality is the same on two languages.

Just noticed that @Quentin mentioned this in the comment section a minute before my edit, well done sir!

Mockup:

$languages = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$default = 'en-US';
/*
 * magic split and structure the language into a array sorted by quality
 *
 * $languages_sorted_by_quality = array(0.8 => ('zh', 'en-US'));
 */
$top_languages = max($languages_sorted_by_quality);
if (isset($top_languages[$default])) {
    $language = $default;
else
    $language = $top_languages[0];
Community
  • 1
  • 1
Torxed
  • 22,866
  • 14
  • 82
  • 131
  • This is available only in IE. As far as I know, there is no way to identify OS language that work under all major browsers. – Kapil Sharma May 07 '13 at 13:23
  • Correct, should probably mentioned that. You'd have to make a sort function on `HTTP_ACCEPT_LANGUAGE`. – Torxed May 07 '13 at 13:23
0

have your tried http_negotiate_language

unasAquila
  • 148
  • 9