我按照BryanH在这里回答的说明:gettext() equivalent in Intl library?并试图用php-intl实现本地化(翻译),但我不断遇到这个人遇到的同样问题:ResourceBundle returns NULL without any errors being raised
他提到他使用工具(我无法弄清楚如何工作)创建了dat文件,而前一个回答中的人似乎只是使用扩展名为.res的txt文件。
如何使用php-intl和ResourceBundle正确实现本地化,以及我做错了什么?
目标是使用不同语言的各种数据文件,以便我可以执行与
类似的操作$t = new Translator();
$t->setResource(new \ResourceBundle('es', 'locales_folder/'));
$t->echo("somestring"); // "el stringo"
..很像第一个答案中的人。此外,目标是拥有易于编辑的文件,因此我可以将它们提供给翻译人员以进行修复,更新等。我意识到我可以通过一个简单的文本文件轻松地通过自定义解决方案来实现这一点,该文件在第一次请求时被解析并保存到memcache中,然后它可以持续存储并获得服务,而无需重新读取.dat文件,但我宁愿在这里采取建议的路线。
编辑:只是为了得到它 - 我成功地用gettext实现了同样的东西并且它很容易 - 除了一个在linux系统中持续存在的bug(http://www.php.net/manual/en/book.gettext.php#91187) - 但我还是要依赖如果可能的话,在更现代和包罗万象的国际扩展中。
答案 0 :(得分:9)
我可以为您提供有关如何为.res
PHP扩展创建和使用intl
文件的问题的解决方案,但是我没有生产系统的速度和使用经验,您将不得不如果这可以替代gettext
,请亲眼看看。
在我看来,gettext
的一大好处是其他工具,例如xgettext
,可以提取要翻译的字符串。尽管如此,在您的用例中使用资源可能更有用。
要生成.res
文件,您需要使用bundled with ICU程序genrb
。 (例如,使用brew install icu4c
(see this tutorial)在OSX上安装ICU时,您可以在/usr/local/Cellar/icu4c/*/bin/genrb
找到该工具(将*
替换为版本号))
接下来,为每个区域设置准备一个文件。我们在本例中使用德语和西班牙语为两种语言执行此操作。
$ cat de.txt
de {
hello { "Hallo" }
}
$ cat es.txt
es {
hello { "Hola" }
}
$ genrb *.txt
genrb number of files: 2
您现在有2个额外的文件de.res
和es.res
,您现在可以在PHP中访问
<?php
foreach (array("de", "es") as $locale) {
$r = ResourceBundle::create($locale, __DIR__);
echo $r["hello"], "\n";
}
将输出
Hallo
Hola
所以从本质上讲,您可以将这些*.txt
文件传递给翻译者并使用genrb
为PHP做好准备。
最后,您尝试撰写的课程的一个小例子:
<?php
class Translator {
private $resourceBundle = null;
public function __construct(\ResourceBundle $r) {
$this->resourceBundle = $r;
}
public function __get($string) {
return $this->resourceBundle[$string];
}
}
$t = new Translator(new \ResourceBundle('es', __DIR__));
echo $t->hello;