PHP语言检测

时间:2009-08-29 18:58:09

标签: php

我是一个试图建立他的第一个多语言网站的爱好者

我使用这段代码来检测用户语言。如果您没有选择一种语言,它将包含基于HTTP_ACCEPT_LANGUAGE的语言文件,我不知道从哪里获取它...

session_start();

if (!isset($_SESSION['lang'])) {
   $_SESSION['lang'] = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
}

elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'en') $_SESSION['lang'] = "en";
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'sv') $_SESSION['lang'] = "sv";
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'pl') $_SESSION['lang'] = "pl";
elseif (isset($_GET['setLang']) && $_GET['setLang'] == 'fr') $_SESSION['lang'] = "fr";

include('languages/'.$_SESSION['lang'].'.php');

它适用于我,包括波兰语文件。但这段代码是否准确?还是有另一种方式?您认为YouTube如何做到这一点?

如果一些英国人,法国人,瑞典人或波兰人可以访问我的网站并查看它是否包含正确的文件,那将会很棒!所以我知道它不适合我:) http://jorm.homeftp.org/

无论如何,你认为我可以改进我的代码?它会显得凌乱,因为我添加更多语言与所有其他人!

由于

9 个答案:

答案 0 :(得分:34)

浏览器通常会发送一个名为Accept-Language的HTTP标头,指示用户愿意使用的语言。

例如,此标头可以是:

Accept-Language: en-us,en;q=0.5

有优先权的概念,顺便说一下; - )

在PHP中,您可以在$_SERVER超级全局:

中获取此信息
var_dump($_SERVER['HTTP_ACCEPT_LANGUAGE']);

会得到我:

string 'en-us,en;q=0.5' (length=14)

现在,你必须解析它; - )


如果我在浏览器的选项中编辑我的偏好,说“我想要法语,如果你不能为我服务法语,请从美国给我英语;如果你也不能告诉我,那就让我英文),标题将是:

Accept-Language: fr-fr,en-us;q=0.7,en;q=0.3

而且,来自PHP:

string 'fr-fr,en-us;q=0.7,en;q=0.3' (length=26)


有关更多信息,您可以查看section 14.4 of the HTTP RFC

你可能在PHP中找到很多代码示例来解析那个头;例如:Parse Accept-Language to detect a user's language

玩得开心!

答案 1 :(得分:7)

这是我用于双语网站的脚本。它将用作index.php的{​​{1}}。根据用户浏览器的语言首选项,如果用户首选语言中的站点不可用,它将重定向到所需语言版本的站点或默认语言站点。

mysite.com

答案 2 :(得分:4)

我知道已经有很多很好的解决方案,但我找到了解决这个问题的方法。

<?php
  $prefLocales = array_reduce(
    explode(',', $_SERVER['HTTP_ACCEPT_LANGUAGE']), 
      function ($res, $el) { 
        list($l, $q) = array_merge(explode(';q=', $el), [1]); 
        $res[$l] = (float) $q; 
        return $res; 
      }, []);
    arsort($prefLocales);
    /*
    This get you from headers like this
      string 'en-US,en;q=0.8,uk;q=0.6,ru;q=0.4' (length=32)
    array like this
    array (size=4)
      'en-US' => float 1
      'en' => float 0.8
      'uk' => float 0.6
      'ru' => float 0.4
    */

代码会将HTTP_ACCEPT_LANGUAGE字符串转换为数组,其中locales为键,权重为值,从高值到低值排序。因此,您可以逐个使用array_shift来获得与您的站点区域设置的最佳匹配。

答案 3 :(得分:3)

您可以使用:Locale::acceptFromHttp()

  

尝试查找可满足HTTP“Accept-Language”标头请求的语言列表的语言环境。

答案 4 :(得分:1)

你的代码看起来很好。如果访问者要求提供您未提供的语言,则可能需要添加最终else默认选项。 此外,如果访问者自己选择了一种语言,您应该将该选项保存在持久性cookie中并检查其值,使其优先于HTTP_ACCEPT_LANGUAGE。

据我所知,Youtube确实使用HTTP_ACCEPT_LANGUAGE,但同时使用IP地理位置来建议在访问者所在国家/地区的语言不匹配时更改语言。绝对讨厌。

只是挑剔:如果你要在列表中添加语言,switch()语句可能更具可读性。

答案 5 :(得分:0)

  

试试这个

function getUserLanguage() {
    $langs = array();

    if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
        // break up string into pieces (languages and q factors)
        preg_match_all(
            '/([a-z]{1,8}(-[a-z]{1,8})?)\s*(;\s*q\s*=\s*(1|0\.[0-9]+))?/i',
            $_SERVER['HTTP_ACCEPT_LANGUAGE'],
            $lang_parse
        );

        if (count($lang_parse[1])) {
            // create a list like 'en' => 0.8
            $langs = array_combine($lang_parse[1], $lang_parse[4]);

            // set default to 1 for any without q factor
            foreach ($langs as $lang => $val) {
                if ($val === '') {
                    $langs[$lang] = 1;
                }
            }
            // sort list based on value
            arsort($langs, SORT_NUMERIC);
        }
    }
    //extract most important (first)
    reset($langs);
    $lang = key($langs);

    //if complex language simplify it
    if (stristr($lang, '-')) {
        list($lang) = explode('-', $lang);
    }

    return $lang;
}

答案 6 :(得分:0)

if(isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])){
    $parts=explode(';',$_SERVER['HTTP_ACCEPT_LANGUAGE']);
    $langs=explode(',',$parts[0]);
    var_dump($langs);
}

答案 7 :(得分:0)

这也是可能的。如果.php不可用,它将使用英语作为默认值。

$lang = substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, 2);
(@include_once 'languages/'.$lang.'.php') or (@include_once 'languages/en.php'); 

答案 8 :(得分:0)

这是从一组支持的语言中选择最佳语言的功能。它从Accept-Language中提取语言,然后根据语言的优先级对给定的语言数组进行排序。

function select_best_language($languages) {
    if (!$_SERVER['HTTP_ACCEPT_LANGUAGE']) return $languages[0];
    $default_q=100;
    foreach (explode(",",$_SERVER['HTTP_ACCEPT_LANGUAGE']) as $lqpair) {
        $lq=explode(";q=",$lqpair);
        if ($lq[1]) $lq[1]=floatval($lq[1]); else $lq[1]=$default_q--;
        $larr[$lq[0]]=$lq[1];
    }
    usort($languages,function($a,$b) use ($larr) { return $larr[$b]<=>$larr[$a]; });
    return $languages[0];
}

$lang = select_best_language(['en','fr','it']);