我使用了@GabrielAnderson的正则表达式,并设计了这个函数,它根据RFC 261 6(当没有给语言赋予质量值时,默认为1)。
当几种语言共享相同的质量值时,最具体的优先于较不具体的优先。(这种行为是不提供任何建议,对于这种特殊情况下的RFC的一部分)
function Get_Client_Prefered_Language ($getSortedList = false, $acceptedLanguages = false)
{
if (empty($acceptedLanguages))
$acceptedLanguages = $_SERVER["HTTP_ACCEPT_LANGUAGE"];
// regex inspired from @GabrielAnderson on http://stackoverflow.com/questions/6038236/http-accept-language
preg_match_all('/([a-z]{1,8}(-[a-z]{1,8})*)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i', $acceptedLanguages, $lang_parse);
$langs = $lang_parse[1];
$ranks = $lang_parse[4];
// (create an associative array 'language' => 'preference')
$lang2pref = array();
for($i=0; $i<count($langs); $i++)
$lang2pref[$langs[$i]] = (float) (!empty($ranks[$i]) ? $ranks[$i] : 1);
// (comparison function for uksort)
$cmpLangs = function ($a, $b) use ($lang2pref) {
if ($lang2pref[$a] > $lang2pref[$b])
return -1;
elseif ($lang2pref[$a] < $lang2pref[$b])
return 1;
elseif (strlen($a) > strlen($b))
return -1;
elseif (strlen($a) < strlen($b))
return 1;
else
return 0;
};
// sort the languages by prefered language and by the most specific region
uksort($lang2pref, $cmpLangs);
if ($getSortedList)
return $lang2pref;
// return the first value's key
reset($lang2pref);
return key($lang2pref);
}
例子:
print_r(Get_Client_Prefered_Language(true, 'en,en-US,en-AU;q=0.8,fr;q=0.6,en-GB;q=0.4'));
输出:
Array
(
[en-US] => 1
[en] => 1
[en-AU] => 0.8
[fr] => 0.6
[en-GB] => 0.4
)
正如你可以看到,“恩'US'出现在第一个位置,尽管'en'是第一个在给定的字符串中。
所以,你可以使用此功能,只需更换您的第一行代码:
$http_lang = substr(Get_Client_Prefered_Language(),0,2);
最好的方法是记录IP及其标题。并稍后检查日志 – zerkms 2011-05-17 23:20:22
[如何从$ _SERVER \ ['HTTP_ACCEPT_LANGUAGE'\]使用PHP获取语言值?](http://stackoverflow.com/questions/2316476/how-to-get-the -language-value-from-serverhttp-accept-language-using-php) – 2011-05-17 23:23:18
这可能是一个案例问题?改变它切换(strtolower($ http_lang))可能会有所帮助。但不知道。 – mjec 2011-05-20 18:28:33