PHP/Gettext问题

Ali*_*xel 18 php locale gettext zend-translate setlocale

我记得几个月前使用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!
Run Code Online (Sandbox Code Playgroud)

这非常有效(如果我没记错的话,在Windows XP和CentOS下),这很好,因为我可以使用任意 "语言环境",而不必担心它们是否安装在系统上.然而,这似乎不再起作用,我想知道为什么......


Red Hat + PHP 5.2.11:

我可以在各种语言环境中来回切换,只要setlocale()调用没有返回false(如果系统上的语言环境可用/已安装),翻译就会显示相关内容.

这并不完美(如果我可以将gettext指向任意翻译目录而不必测试是否存在语言环境,那将是很好的),但这是可以接受的.我稍后会再进行一些测试.

Windows 7 + PHP 5.3.1(XAMPP):

setlocale()总是返回false(即使使用LC_ALL而不是LC_MESSAGES),除非我使用一些有效的Windows语言环境,例如eng,deuptg- 在这种情况下,语言环境似乎正确设置但翻译仍未显示.我现在无法测试,因为我已经打开了数百个标签但是我认为第一次调用该脚本会产生正确的转换(重启Apache不会起作用).

我不确定这是否与PHP Bug#49349有关.我将测试这是几个小时.


有没有办法在不同的操作系统中可靠地使用gettext扩展(不是纯PHP实现,如php-gettextZend Translate Adapter)(可能有自定义语言环境l33t)?

另外,是否绝对有必要使用setlocale(LC_ALL, ...)?我会保持离开TIME,NUMERIC并且MONETARY(特别)语言环境设置不受影响(默认为POSIX语言环境).


我有一个想法......是否可以setlocale()使用非常常见的语言环境(如C,POSIXen_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
Run Code Online (Sandbox Code Playgroud)

这可以在*nix和Windows plataforms上运行吗?

mar*_*rio 18

Gettext对于webapps来说并不太实用.

  • 例如,它本身不尊重/使用Accept-Language样式首选项.
  • 通常会在共享的webhosts(mod_php SAPI)上引发一些缓存问题.

所以我有时希望PHP模块不存在,并且方便的_()函数名称快捷方式可用于userland实现.
(如果我自己的gettext.php,它更可靠.)

你的选择:

  1. Anway,根据一些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.(因为你的源文本仍然是英文,关心字符集在这里并不是很相关;但可能是gettext跳过它自己的常见情况.)哦,有时候它是UTF8而不是UTF-8; 也尝试ASCII.

  2. 或者绕过gettext.您的域名想法很接近,但我只是使用预定义的./locale/子语言:

    ./lang/en/locale/C/LC_MESSAGES/domain.mo
    
    Run Code Online (Sandbox Code Playgroud)

    然后只是调用bindtextdomain("default", "./lang/{$APP_LANG}/locale")而不给gettext空间解释多少.它总是会查找/ C /,但已经注入了正确的语言环境目录.但是尝试在那里有一个从$ LANG到/ C /的符号链接.

  3. 在牛羚咬一口.放弃gettext."PhpWiki"有一个自定义awk转换脚本.它将.po文件转换为.php数组脚本(是的,非常oldschool),而只是使用__()函数.关.而且更可靠.

  • 责任在于PHP而不是`gettext`,你可以尝试使用ICU模块来解析`HTTP_ACCEPT_ENCODING`而PHP的用户也是如此:http://stackoverflow.com/q/5788824/175849 (5认同)

med*_*iev 6

这段代码不能在每个系统上完美运行,因为每个系统locale repository + php版本都是不同的.

如果你想要一致性,你需要使用像Zend_Translate这样的东西,如果你在每个系统上安装Zend(它的相同版本),它们将彼此一致,因为它们使用相同的本地化数据,区域设置名称和代码库.

有很多错误setlocale,它只是不可靠.请参阅评论@ http://php.net/manual/en/function.setlocale.php