23

这是php 手册中的一小段代码:

putenv('LC_ALL=zh_CN');
setlocale(LC_ALL, 'zh_CN');

bindtextdomain('domain', './locale');
textdomain('domain');

echo gettext('Hello');

它将输出文件中定义的你domain.mo,但问题是只要 Apache 正在运行,gettext()总是返回缓存的结果。

如果我将 Hello 的翻译更改您好domain.mo仍然会输出您好

但是,可以通过将和的domain参数更改为新名称来解决此问题。喜欢从到。但是每次更新文件时编辑php文件真的很痛苦。bindtextdomain()textdomain()"domain""domain2".mo

有没有更好的方法来做到这一点,比如删除一些文件夹或调用一些 php 函数来完成这项工作?这样我就可以为此目的编写一个小脚本。

4

6 回答 6

17

每个解决方案(123)都建议更改domain以摆脱缓存问题,但这会在内存中创建大量过期缓存。

因此,我深入研究了 gnu-gettext 源以获取有关缓存策略的详细信息(bindtextdom.c:78。)

调用时bindtextdomain(domain, dirname)会检查domain缓存中是否存在;如果是这样,它将检查是否dirname与缓存中的相同。如果这失败了,它将强制为同一个域刷新缓存,而不是在内存中创建一个新的。

修复非常简单,首先创建一个指向存储文件的locale文件夹的虚拟链接.mo

cd locale
ln -s . nocache

然后在前面加一行bindtextdomain()

bindtextdomain('domain', './locale/nocache');
bindtextdomain('domain', './locale');

现在每次都强制刷新缓存。


更新:

这种 hack 在某些情况下可能不起作用(无法弄清楚确切的条件。)这个解决方案应该在生产环境中使用,但只适用于那些需要在保持 httpd 运行的同时修复某些问题的人!

只要可以,请避免从一开始就使用 gettext,这确实是古老的东西,应该永远弃用。

于 2012-11-29T15:25:31.160 回答
14

我在从toclearstatcache();翻译后调用了函数,它工作正常而无需重新启动 apache。加载我在任何语言文件中所做的每个更改。messages.pomessages.mo

于 2013-09-23T06:46:56.770 回答
7

好的,在我的情况下,我需要通过 service php5.6-fpm-sp restart 重新启动 phpfpm。

如果你使用 php-fpm 你必须重启 phpfpm 以清除 gettext 的缓存,重启 apache2 不起作用。

希望对其他人有用。

于 2015-02-07T13:36:46.600 回答
1

恕我直言,没有直接的方法可以做到这一点(除了您提到的域解决方法),这就是我们使用php-gettext的原因。

更新:我们已经开始将其维护为motranslator,可由 Composer 安装并与所有 PHP 版本兼容。

于 2012-11-29T14:57:00.410 回答
1

我的解决方案是使用不同的名称保存文件,例如使用日期,然后更改域:

#the path for a domain, the .mo files must match the domain
#the trick to avoid permanent caching, is to use different names for the domain,             like the date messages_180320151250
$domain = 'messages_180320151300';

#sets the path for a domain, the .mo files must match the domain
bindtextdomain($domain, $_SERVER['DOCUMENT_ROOT']."/apps/cp/locale");

textdomain($domain);
于 2015-03-18T14:16:38.517 回答
0

使用apachectl graceful命令要求进程重新读取配置。它将在请求完成服务后结束请求。所以看起来很安全。

根据Apache HTTP Server 2.2 文档

USR1 或优雅信号使父进程建议子进程在当前请求后退出(或者如果它们没有提供任何服务,则立即退出)。父级重新读取其配置文件并重新打开其日志文件。随着每个孩子的死亡,父母用新一代配置中的孩子替换它,立即开始服务新请求。

它对我有用。

于 2018-04-03T02:56:43.020 回答