2011-12-19 132 views
8

我有一个PHP后端,几种类型的设备通过公共API进行通信。请求通常包含响应所需的语言(例如'en'或'fr'或'ru'等) - 但不是完整的语言环境。这在过去几年里我所需要的一切都很好。但是现在我需要在响应中包含日期信息 - 并且需要使用语言环境来格式化日期。在PHP中获取语言的默认语言环境

如何从语言中获取语言环境?我明白一种语言不足以唯一标识语言环境,但我至少需要一些东西。如果我可以获得至少一个区域设置,例如'en'或'ru_RU'代表'ru'等等 - 这就足够了。

回答

6

想过更多关于这个问题和我有特定的设置,我想出了这个解决方案,这似乎工作。请注意,我无法控制需要支持哪些语言:将翻译文件放入预定义位置并由其他人安装系统区域设置。在运行期间,如果存在相应的翻译文件并且安装了系统区域设置,则需要支持特定的语言。这让我对这个解决方案:

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安装(我们位于英国就像我们的服务器)。

+0

没有看到你的答案提出了类似的东西,但是封装到一个'System'类中,封装了'System-> getLocales()'方法。但它的作用是一致的。 – hakre 2011-12-31 14:24:13

1

我理解你是否正确,你只需要一个语言地图(如en)到语言环境(如en_GB)?如果是这样,你可以编译一个给你使用语言:

$localeMap = array(
    'en' => 'en_GB', 
    'fr' => 'fr_FR', 
    # ... 
); 

# Usage: 

$locale = $localeMap[$lang]; 

但这是那么微不足道,我不能确定,如果我正确地理解你的问题。

如果你不确定的语言环境是什么样的语言,只需要这应该是一个有效的区域设置语言本身,只是没有一个国家:

升=> 1

只要语言是双字母格式,对我来说看起来很好(ISO标准639,“语言名称表示法代码”),另请参见Tags for the Identification of Languages (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); 
+0

是的,这是我的第一个想法,但是我并不事先知道我使用的所有语言,因为翻译是由第三方提供的,而且语言环境由系统管理员安装在系统上。所以,理论上,我必须在运行时动态枚举可用的语言环境,并在该阶段选择一个。其中,其本身可能并不是一个坏主意,实际上...... – 2011-12-20 09:30:33

+0

您准确使用哪种语言环境格式?为了哪个目的/在哪些功能?请参见[标识语言标识(RFC 1766)](http://www.ietf.org/rfc/rfc1766.txt) – hakre 2011-12-20 11:26:21

+0

感谢您的澄清。我的语言采用标准的双字母格式。在调用'strftime'之前,我需要'setlocale'的语言环境。 – 2011-12-20 12:11:36

1

也许你可以为了得到语言环境使用$_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,允许用户显式地设置自己的语言环境,只要确保它会优雅地回落到你现在选择实施的任何系统。

+0

感谢您的回答。这可能是一个很好的窍门,但它不适用于所有情况。设想一个网站,顶部有一个语言选择。我可能坐在英格兰的电脑上,只有英文为'accepted_language',但是我把这个网站改成了法文。我会期待法语结果,但'$ _SERVER ['HTTP_ACCEPT_LANGUAGE']'和'Locale :: acceptFromHttp'方法都会返回'en_GB'。当然,如果一切都像网站一样简单,我就不会有问题。 – 2011-12-20 09:30:01

相关问题