2011-09-19 100 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";