8

有没有一种简单的方法来解析用户的 HTTP_ACCEPT_LANGUAGE 并在 PHP 中设置语言环境?

我知道 Zend 框架有一种方法可以做到这一点,但我宁愿不安装整个框架只是为了使用那一点功能。

PEAR I18Nv2 包处于测试阶段,近三年没有更改,所以如果可能的话,我宁愿不使用它。

如果它能够确定服务器是否在 Windows 上运行也很好,因为 Windows 的语言环境字符串与世界其他地方的字符串不同......(德语是“deu”或“german”而不是“de”。 )

4

4 回答 4

5

这并不像应该的那么容易(以我的拙见)。首先,您必须从中提取语言环境并按其值$_SERVER['HTTP_ACCEPT_LANGUAGE']对它们进行排序。q之后,您必须为每个给定的语言环境检索适当的系统语言环境,这在 *nix 机器上应该没问题(您可能只需要处理正确的字符集),但在 Windows 上,您必须将语言环境转换为例如,Windows 语言环境de_DE将是German_Germany(同样,如果您在应用程序中使用 UTF-8,您还必须处理字符集问题)。我认为你必须为这个问题建立一个查找表 - 并且有很多语言环境;-)

不,您尝试一个接一个的语言环境(按降序排列q),直到找到匹配项(如果无法设置给定的语言环境,setlocale()该函数将返回)。false

但接下来会有最后一个障碍需要应对:

语言环境信息是按进程维护的,而不是按线程维护的。如果您在 Windows 上的 IIS 或 Apache 等多线程服务器 api 上运行 PHP,您可能会在脚本运行时遇到语言环境设置的突然更改,尽管脚本本身从未调用 setlocale() 本身。这是由于在同一进程的不同线程中运行的其他脚本同时使用 setlocale() 更改了进程范围的语言环境。

(见:http ://de2.php.net/manual/en/function.setlocale.php )

这意味着您可能会在执行脚本期间遇到突然的区域设置更改,因为具有不同区域设置的另一个用户刚刚访问了您的网页。

因此,上面提到的Zend_Locale不依赖于 PHP 函数setlocale()(它仅用于检索系统区域设置信息),而是使用基于Unicode CLDR Project提供的数据的系统。这使得组件独立于所有这些setlocale()问题,但这也引入了一些其他缺陷,例如缺乏对区域感知字符串操作的支持(例如排序)。

于 2008-11-29T10:39:32.213 回答
2

不错的解决方案即将推出

没有它,您将需要解析该标头。它是以逗号分隔的以分号分隔的语言环境和属性列表。

它看起来像这样:

en_US, en;q=0.8, fr_CA;q=0.2, *;q=0.1

然后尝试每个语言环境,直到setlocale()接受它。准备好它们都不匹配。

不要基于它太重要或允许用户覆盖它,因为某些用户可能配置错误的浏览器。


对于 Windows 语言环境,也许您需要将 ISO 639-1 名称转换为 ISO 639-2/3?

于 2008-11-29T02:09:13.850 回答
2

我知道 Zend 框架有一种方法可以做到这一点,但我宁愿不安装整个框架只是为了使用那一点功能。

Zend 的好消息是,您不需要全部安装。这是一个松散耦合的框架,您可以只使用 Zend_Locale 而无需使用任何其他组件。也许您想将它与 Zend_Translate 结合使用。

看看这个

于 2008-11-29T11:04:38.293 回答
1

http_negotiate_language,但它取决于 http 扩展名。或者,请参阅手册页上的注释以获取用户空间实现。

于 2008-11-29T12:02:36.647 回答