获取PHP中语言的默认语言环境


Get default locale for language in PHP

我有一个PHP后端,几种类型的设备通过公共API与之通信。请求通常包含响应所需的语言(例如:'en'或'fr'或'ru'等)-但不是完整的区域设置。在过去的几年里,这对我需要的一切都很有效。但是现在我需要在响应中包含日期信息-并且需要一个区域设置来格式化日期。

如何从语言中获得区域设置?我确实明白,一种语言不足以唯一地标识一个地区,但我至少需要一些东西。如果我能得到至少一个地区,例如en_GB为'en'或'ru_RU'为'ru',等等-这将是足够的。

在对问题和我所拥有的特定设置进行了更多思考后,我提出了这个解决方案,它似乎有效。请注意,我无法控制需要支持哪些语言:翻译文件被放入预定义的位置,系统区域设置由其他人安装。在运行时,如果存在相应的翻译文件并且安装了系统语言环境,则需要支持特定的语言。这让我想到了这个解决方案:

function getLocale($lang)
{
    $locs = array();
    exec('locale -a', $locs);
    $locale = 'en_GB';
    foreach($locs as $l)
    {
        $regex = "/$lang'_[A-Z]{2}$/";
        if(preg_match($regex, $l) && file_exists(TRANSROOT . "/$lang.php"))
        {
            $locale = $l;
            break;
        }
    }
    return $locale;
}

如果我无法解析语言环境,我默认使用en_GB,因为我确定en_GB已安装(我们位于英国,我们的服务器也位于英国)。

也许您可以使用$_SERVER['HTTP_ACCEPT_LANGUAGE'];而不是提供的语言来获得区域设置。通常,这将包含使用连字符而不是下划线的实际区域设置。

示例$_SERVER['HTTP_ACCEPT_LANGUAGE']:

en-ca,en;q=0.8,fr-ca;q=0.5,fr;q=0.3

只要在第一个,之前得到所有东西,就可以了。这也比填充区域设置数组要好,因为它让浏览器告诉服务器它喜欢什么语言,而不是其他方式,但是,在hakre的答案中,数组应该用作备份系统,以防提供无效/空/缺失的$_SERVER['HTTP_ACCEPT_LANGUAGE']

你可能还想看看locale类和locale::acceptFromHttp方法

另外,您可能需要考虑修改您的API以允许用户显式地设置他们的区域设置,只需确保它将优雅地退回到您现在选择实现的任何系统。

我理解你正确吗,你只需要一个从语言(如en)到区域设置(如en_GB)的映射?如果是,您可以为您使用的语言编译一个:

$localeMap = array(
    'en' => 'en_GB',
    'fr' => 'fr_FR',
    # ...  
);
# Usage:
$locale = $localeMap[$lang];

但是这太微不足道了,我不确定我是否正确理解了你的问题。

如果您不确定语言的区域设置是什么,只需使用语言本身,这应该是一个有效的区域设置,只是没有国家:

l => ll

只要语言是两个字母的格式对我来说看起来很好(ISO标准639,"语言名称表示的代码"),也请参阅语言标识的标签(RFC 1766)。

$locale = isset($localeMap[$lang]) ? $localeMap[$lang] : $lang;

但是,这可能会有所不同,这取决于您使用的函数所期望的区域设置格式。


class System
{
    /**
     * @return array
     */
    public function getLocales()
    {
        $locales = array();
        exec('locale -a', $locales, $retCode);
        !$retCode || $locales = array();
        return $locales;
    }
    /**
     * @return string something matching 
     * @note Improve by creating your system aware locale class to move
     *       away the responsibility to map system locales onto strings
     *       of certain kinds and to deal with the different locale types.
     */
    public function getLocaleByLang($lang)
    {
        ...
    }
}

$lang = ...
$system = new System;
$locale = $system->getLocaleByLang($lang);