Как вы уже предполагали в своем вопросе, вам нужно проанализировать заголовок Accept-Language
HTTP / 1.1 , который доступен на PHP в $_SERVER['HTTP_ACCEPT_LANGUAGE']
.Сначала нужно разобрать структуру, которую вы можете лучше обработать в PHP, например, массив:
/**
* Convert Accept Language to sorted PHP array
*
* Related HTTP Specs:
* <http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4>
* <http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.9>
*
* @param string $accept header value
* @return array ([language-range] => qvalue, ...)
*/
function http_accept_language_array($accept = NULL)
{
if (!$accept && isset($_SERVER['HTTP_ACCEPT_LANGUAGE']))
$accept = $_SERVER['HTTP_ACCEPT_LANGUAGE'];
$accept = (string) $accept;
$pattern = '/([a-z]{1,8}(-[a-z]{1,8})?)(;q=([01](?:\.[0-9]{0,3})?))?(?=$|,[ ]*)/i';
preg_match_all($pattern, $accept, $matches);
$array = array();
if (count($matches[1]))
{
list(, $ranges,,, $qvals) = $matches;
# normalize ranges
foreach ($ranges as &$range)
$range = strtolower($range);
unset ($range);
# set default qvalue 1
foreach ($qvals as &$qval)
if ('' === $qval) $qval = '1';
unset ($qval);
$array = array_combine($ranges, $qvals);
arsort($array, SORT_NUMERIC);
}
return $array;
}
, который для da, en-gb;q=0.8, en;q=0.7
вернет:
array(3) {
["da"] => string(1) "1"
["en-gb"] => string(3) "0.8"
["en"] => string(3) "0.7"
}
Затем вам нужноПроанализируйте этот отсортированный массив, чтобы найти первое совпадение, установив предпочтение с помощью значения en
по умолчанию:
$lang = 'en';
foreach (http_accept_language_array() as $range => $qvalue)
{
if (preg_match('/^zh[$-]/', $range))
{
$lang = 'cn';
break;
}
}
Наконец, вы можете выполнить перенаправление на основе $lang
(или включить или что-то еще):
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/$lang/");
Если вы ищете готовую библиотеку для решения этой проблемы, одним из существующих решений является Symfony HttpFoundation\Request
или в PEAR естьHTTP::negotiateLanguage
.
Расширение intl PHP имеет еще одну низкоуровневую функцию, которая связана, однако она не предлагает массив, но имеет одно значение: locale_accept_from_http
Другим общим ресурсом для получения дополнительной информации, связанной с HTTP, является Расширенная обработка запросов HTTP в PHP .