如何创建用于PHP的ICU资源文件?

Swa*_*der 5 php localization gettext internationalization icu

我按照BryanH的回答说明:在Intl库中等效的gettext()?并试图用php-intl实现本地化(翻译),但我一直遇到这个人有同样的问题:ResourceBundle返回NULL而没有引发任何错误

他提到他使用工具创建了dat文件(我无法弄清楚如何工作),而前一个回答中的人似乎只是使用扩展名为.res的txt文件.

如何使用php-intl和ResourceBundle正确实现本地化,我做错了什么?

目标是拥有不同语言的各种数据文件,以便我可以做类似的事情

$t = new Translator();
$t->setResource(new \ResourceBundle('es', 'locales_folder/'));
$t->echo("somestring"); // "el stringo"
Run Code Online (Sandbox Code Playgroud)

..就像第一个回答中的那个人一样.此外,目标是拥有易于编辑的文件,因此我可以将它们提供给翻译人员以进行修复,更新等.我意识到我可以通过一个简单的文本文件轻松地使用自定义解决方案来实现这一点,该文件在第一次请求时被解析并保存到memcache中,然后它可以持久存储并从中获取服务而无需重新读取.dat文件,但我宁愿在这里采取建议的路线.

编辑:只是为了得到它 - 我成功地用gettext实现了同样的东西并且它很容易 - 除了一个在linux系统中持续存在的bug(http://www.php.net/manual/en/book.gettext) .php#91187) - 但如果可能的话,我想依靠更现代和包罗万象的国际扩展.

aki*_*irk 9

我可以为您提供有关如何.resintlPHP扩展创建和使用文件的问题的解决方案,但是我没有速度和在生产系统中使用的经验,您必须亲自了解它是否可以替代gettext.

在我看来,gettext其他工具的好处是xgettext可以提取要翻译的字符串.尽管如此,在您的用例中使用资源可能更有用.

要生成一个.res文件,你需要使用该程序genrb捆绑了ICU.(例如,在OSX上使用brew install icu4c(参见本教程)安装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
Run Code Online (Sandbox Code Playgroud)

你现在有2个额外的文件de.reses.res,你现在可以在PHP访问

<?php
foreach (array("de", "es") as $locale) {
    $r = ResourceBundle::create($locale, __DIR__);
    echo $r["hello"], "\n";
}
Run Code Online (Sandbox Code Playgroud)

哪个会输出

Hallo
Hola
Run Code Online (Sandbox Code Playgroud)

所以从本质上讲,您可以将这些*.txt文件交给翻译器,并使用它们为PHP做好准备genrb.

最后,您尝试编写的类的一个小示例:

<?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;
Run Code Online (Sandbox Code Playgroud)