1

我有一个multi-language页面,我想检测客户端浏览器的语言,然后制作一个 301 主页或其他东西。但我不确定哪种方式更适合 seo。不知道web spider喜欢哪一个?还是其他方式?

<?php 
$LG=$_SERVER['HTTP_ACCEPT_LANGUAGE']; 
if (preg_match('/^[zZ][hH]/', $LG)) {
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/cn/");
exit();} //jump to chinese version
else { 
header("HTTP/1.1 301 Moved Permanently");
header("Location: http://mydomain.com/en/");
exit();} //jump to english version
?>

或者

<?php 
$LG=$_SERVER['HTTP_ACCEPT_LANGUAGE']; 
if (preg_match('/^[zZ][hH]/', $LG)) {
include ("http://mydomain.com/cn/");
} //include chinese version
else { 
header("HTTP/1.1 301 Moved Permanently");
include ("http://mydomain.com/en/");
} //include english version
?>

或者其他方式?谢谢。

4

2 回答 2

2

正如您在问题中已经假设的那样,您需要解析Accept-LanguageHTTP/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;
}

哪个 forda, 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.

PHP intl 扩展有另一个相关的低级函数,但是它不提供数组而是单个值:locale_accept_from_http

有关更多 HTTP 相关信息的另一个通用资源是PHP 中 HTTP 请求的高级处理

于 2011-11-11T09:22:36.280 回答
2

我建议为每种语言使用不同的 URL(选项 2)。这将使分析变得更加容易(如果您使用 /en、/cn、结构,Google Analytics 可以显示哪种语言更受欢迎)。

此外,用户可以收藏和分享正确的语言,并从另一台计算机返回。

最重要的是,当蜘蛛试图索引页面时,让相同的规范 URL 服务于两种不同的语言会造成严重破坏。索引的内容将是不可预测的。

于 2011-11-11T08:27:19.060 回答