PHP / Gettext问题?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (16)

我记得几个月前用gettext运行一些测试,下面的代码完美工作:

putenv('LANG=l33t');
putenv('LANGUAGE=l33t');
putenv('LC_MESSAGES=l33t');

if (defined('LC_MESSAGES')) // available if PHP was compiled with libintl
{
    setlocale(LC_MESSAGES, 'l33t');
}

else
{
    setlocale(LC_ALL, 'l33t');
}

bindtextdomain('default', './locale'); // ./locale/l33t/LC_MESSAGES/default.mo
bind_textdomain_codeset('default', 'UTF-8');
textdomain('default');

echo _('Hello World!'); // h3110 w0r1d!

如果我没有记错的话,这个工作很完美(在Windows XP和CentOS下),这很好,因为我可以使用任意的 “语言环境”,而不必担心它们是否安装在系统上。但是,这似乎并没有工作了,我想知道为什么......

Red hat+ PHP 5.2.11:

只要setlocale()呼叫不返回错误(如果区域设置可用/安装在系统上),我就能够从各种语言环境来回切换,并且翻译显示正确性。

这并不完美(如果我可以将gettext指向任何任意的转换目录而不必测试locale的存在,那就太棒了),但这是可以接受的。我稍后会运行更多的测试。

Windows 7 + PHP 5.3.1(XAMPP):

setlocale()总是返回false(即使使用LC_ALL而不是LC_MESSAGES),除非我使用一些有效的Windows语言环境,例如engdeu或者ptg- 在这种情况下,语言环境似乎设置正确,但翻译仍然不显示。我现在无法进行测试,因为我打开了数百个选项卡,但我认为第一次调用该脚本会产生正确的翻译(重新启动Apache不会这么做)。

有没有办法使用gettext扩展可靠地跨不同操作系统(可能带有自定义喜欢的语言环境l33t)?

另外,使用它是绝对必要的setlocale(LC_ALL, ...)吗?我会保留TIMENUMERIC并且MONETARY(特别是)区域设置保持不变(默认为POSIX区域设置)。

我有一个想法...是否可以setlocale()使用非常常见的语言环境(如CPOSIXen_US)调用并通过域指定语言?像这样的东西:

/lang/C/LC_MESSAGES/domain.pt.mo
/lang/C/LC_MESSAGES/domain.de.mo
/lang/C/LC_MESSAGES/domain.en.mo
/lang/C/LC_MESSAGES/domain2.pt.mo
/lang/C/LC_MESSAGES/domain2.de.mo
/lang/C/LC_MESSAGES/domain2.en.mo

这可以在* nix和Windows平台上工作吗?

提问于
用户回答回答于

Gettext对于web应用程序来说并不太实际。

  • 例如,它本身不承认/使用Accept-Language样式偏好。
  • 通常会在共享虚拟主机上引发一些缓存问题(mod_php SAPI)。

所以我有时希望PHP模块不存在,并且方便的_()函数名称快捷键可用于用户区实现。

你的选择:

  1. 根据一些bug报告,gettext的Windows端口在UTF-8上有一些缺陷。也许你的版本再次受到影响。所以尝试bind_textdomain_codeset('default', 'ISO-8859-1');初学者。另外,它似乎更喜欢Windows IIRC上的环境变量,所以putenv("LC_ALL", "fr_FR");可能比setlocale()。尤其适用于以后的dl(gettext.dll)。 也给它一个包括字符集在那里的机会LANG=en_GB.ISO-8859-1。(因为无论如何你的源文本是英文的,关心charset在这里并不是非常重要,但可能是gettext跳过它自身的一个常见情况。)哦,有时它是UTF8而不是UTF-8; 也尝试ASCII。
  2. 或者绕过gettext。你的域名想法很接近,但我只是简单地为语言使用预定义的./locale/子目录: ./lang/en/locale/C/LC_MESSAGES/domain.mo 然后只需调用bindtextdomain("default", "./lang/{$APP_LANG}/locale")gettext空间来解释很多。它将始终查找/ C /,但正确的语言环境目录已被注入。但是,无论如何,尝试从$ LANG到/ C /都有一个符号链接。
  3. 放弃gettext。“PhpWiki”有一个自定义的awk转换脚本。它将.po文件转换成.php数组脚本(yeah very oldschool),并且只是使用__()函数。关。而且更可靠。
用户回答回答于

这些代码不会在每个系统上完美运行,因为每个系统语言环境信息库+ php版本都是不同的。

如果你想要一致性,你需要使用像Zend_Translate这样的东西,如果你在每个系统上安装Zend(它的版本相同),它们将会彼此保持一致,因为它们使用相同的本地化数据,语言环境名称和代码库。

扫码关注云+社区