2011-09-19 66 views
2

我设置了我的网站,因此我只需添加“?lang = en”或“?lang = es”即可更改英语/西班牙语。PHP或htaccess通过Accept-Language重写URL?

当我进入网站时,例如“http://domain.com/something/something_else?lang=es”,设置了一个cookie,以便继续以该语言浏览网站。

我想首先通过浏览器的“接受语言”值重定向我的用户,但如果他们愿意,可以让他们继续以其他语言浏览网站。

什么是最好的方法来做到这一点? .htaccess会与选择语言时设置的cookie一起工作吗?

编辑:这是我更新的代码与保罗回答:

EDIT2:哦,我只是有“恩”和“ES”的语言。我不知道这个代码wpuld如何只选择之间的两个或设置默认...:/

if (isset($_GET["lang"])) 
     $this->setLanguage($_GET["lang"]); 
    elseif (isset($_COOKIE["language"])) 
     $this->setLanguage($_COOKIE["language"]); 
    elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) 
     { 
     // Parse the Accept-Language according to: 
     // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 
     preg_match_all(
      '/([a-z]{1,8})' . // First part of language e.g en 
      '(-[a-z]{1,8})*\s*' . // other parts of language e.g -us 
      // Optional quality factor 
      '(;\s*q\s*=\s*((1(\.0{0,3}))|(0(\.[0-9]{0,3}))))?/i', 
      $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
      $langParse); 

     $langs = $langParse[1]; 
     $quals = $langParse[4]; 

     $numLanguages = count($langs); 
     $langArr = array(); 

     for ($num = 0; $num < $numLanguages; $num++) 
     { 
      $newLang = strtoupper($langs[$num]); 
      $newQual = isset($quals[$num]) ? 
       (empty($quals[$num]) ? 1.0 : floatval($quals[$num])) : 0.0; 

      // Choose whether to upgrade or set the quality factor for the 
      // primary language. 
      $langArr[$newLang] = (isset($langArr[$newLang])) ? 
       max($langArr[$newLang], $newQual) : $newQual; 
     } 

     // sort list based on value 
     arsort($langArr, SORT_NUMERIC); 
     $acceptedLanguages = array_keys($langArr); 
     $preferredLanguage = reset($acceptedLanguages); 

     $this->setLanguage($preferredLanguage); 
    } 
    else 
     $this->setLanguage("en"); 

回答

2

我这样做是在PHP。接受语言是一件复杂的事情。浏览器可以建议一种以上的语言,它们会接受(每种语言都有一个显示喜欢的质量因素)。对于我的网站,我有一个默认语言可供显示(当我的翻译列表中没有任何Accept-Languages时,会显示该语言)。否则,如果没有语言设置(setLang),我通过解析Accept-Language来基于浏览器最可接受的方式来选择它。我使用的函数如下(它包含我的会话管理器设置cookie - 但你可以通过直接调用$ _SESSION [etc] = $ foo;)来重新实现。

编辑:不幸的是我的网站只对主要语言(EN,ES,FR),而不是翻译(EN_US,EN_GB,es_MX,es_ES),所以我选择在这些为主要语言指定的最高品质因数。

public function setLanguage($setLang='') 
    { 
     if (!empty($setLang)) 
     { 
     $this->setup['Session']->set($this->setup['Lang_Key'], $setLang); 
     } 
     else 
     { 
     if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) 
     { 
      // Parse the Accept-Language according to: 
      // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 
      preg_match_all(
       '/([a-z]{1,8})' . // First part of language e.g en 
       '(-[a-z]{1,8})*\s*' . // other parts of language e.g -us 
       // Optional quality factor 
       '(;\s*q\s*=\s*((1(\.0{0,3}))|(0(\.[0-9]{0,3}))))?/i', 
       $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
       $langParse); 

      $langs = $langParse[1]; 
      $quals = $langParse[4]; 

      $numLanguages = count($langs); 
      $langArr = array(); 

      for ($num = 0; $num < $numLanguages; $num++) 
      { 
       $newLang = strtoupper($langs[$num]); 
       $newQual = isset($quals[$num]) ? 
        (empty($quals[$num]) ? 1.0 : floatval($quals[$num])) : 0.0; 

       // Choose whether to upgrade or set the quality factor for the 
       // primary language. 
       $langArr[$newLang] = (isset($langArr[$newLang])) ? 
        max($langArr[$newLang], $newQual) : $newQual; 
      } 

      // sort list based on value 
      arsort($langArr, SORT_NUMERIC); 
      $acceptedLanguages = array_keys($langArr); 
      $preferredLanguage = reset($acceptedLanguages); 

      $this->setup['Session']->set(
       $this->setup['Lang_Key'], $preferredLanguage); 
     } 
     else 
     { 
      $this->setup['Session']->set(
       $this->setup['Lang_Key'], $this->setup['Default_Language']); 
     } 
     } 

     return $this->setup['Session']->get($this->setup['Lang_Key']); 
    } 
+0

感谢保罗..我更新了我的问题与您的代码,但我不太确定如何使用它。我在PHP编码方面很新,你能检查我做错了什么吗?无论如何,感谢您分享您的代码! – Santiago

+0

解析语言接受头文件的相关PHP函数我在这里写入了一个更长的答案:[301页主页上seo和侦探浏览器语言的更好方法](http:// stackoverflow。COM /问题/ 8091296 /什么 - 是 - 一 - 更好的方式换搜索引擎优化和侦探浏览器的语言为-301家庭页/ 8091897#8091897) – hakre

0

我在PHP中这样做。接受语言是一件复杂的事情。浏览器可以建议一种以上的语言,它们会接受(每种语言都有一个显示喜欢的质量因素)。

不幸的是,我的网站只有主要语言(EN,ES,FR)的翻译,而不是(en_US,en_GB,es_MX,es_ES),所以我选择这些主要语言中指定的最高质量因子。

下面是一个未经测试的编辑应该从我的代码中删除大部分或所有的依赖关系。对不起,以前的回答让我感到困惑。我对我的函数进行了一些调用,其中一些语言检查在其他地方完成。下面的代码应该设置会话语言变量,您应该在别处使用它来确定正确的翻译。

这似乎比我以前的答案复杂得多,我不得不在我自己的代码中实现这一点。对于需要特定翻译的人员(EN_US,EN_GB),应修改以下代码,以考虑preg_match_all中的匹配2。

$websiteLanguages = array('EN', 'ES'); 
session_start(); 

// The user wants a specific language regardless of their accept settings. 
if (isset($_GET["lang"])) 
{ 
    $_SESSION["language"] = $_GET["lang"]; 
    return; 
} 

// A language has already been decided upon. 
if (isset($_SESSION["language"])) 
{ 
    return; 
} 

// No language has been chosen we should choose from the accept language. 
if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) 
{ 
    // Parse the Accept-Language according to: 
    // http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 
    preg_match_all(
     '/([a-z]{1,8})' . // M1 - First part of language e.g en 
     '(-[a-z]{1,8})*\s*' . // M2 -other parts of language e.g -us 
     // Optional quality factor M3 ;q=, M4 - Quality Factor 
     '(;\s*q\s*=\s*((1(\.0{0,3}))|(0(\.[0-9]{0,3}))))?/i', 
     $_SERVER['HTTP_ACCEPT_LANGUAGE'], 
     $langParse); 

    $langs = $langParse[1]; // M1 - First part of language 
    $quals = $langParse[4]; // M4 - Quality Factor 

    $numLanguages = count($langs); 
    $langArr = array(); 

    for ($num = 0; $num < $numLanguages; $num++) 
    { 
     $newLang = strtoupper($langs[$num]); 
     $newQual = isset($quals[$num]) ? 
      (empty($quals[$num]) ? 1.0 : floatval($quals[$num])) : 0.0; 

     // Choose whether to upgrade or set the quality factor for the 
     // primary language. 
     $langArr[$newLang] = (isset($langArr[$newLang])) ? 
      max($langArr[$newLang], $newQual) : $newQual; 
    } 

    // sort list based on value 
    // langArr will now be an array like: array('EN' => 1, 'ES' => 0.5) 
    arsort($langArr, SORT_NUMERIC); 

    // The languages the client accepts in order of preference. 
    $acceptedLanguages = array_keys($langArr); 

    // Set the most preferred language that we have a translation for. 
    foreach ($acceptedLanguages as $preferredLanguage) 
    { 
     if (in_array($preferredLanguage, $websiteLanguages)) 
     { 
      $_SESSION['Language'] = $preferredLanguage; 
      return; 
     } 
    } 
} 

// We will have returned by now if a language could be chosen, otherwise use 
// our default language. 
$_SESSION['Language'] = "EN";