CakePHP i18n __函数返回数组

时间:2016-05-16 01:33:36

标签: cakephp internationalization cakephp-3.0 auraphp

我遇到了__函数的问题,我不确定它是否是Cake(3.2.8),Aura \ Intl或我的代码中的错误。我在Cake 1.3中尝试了同样的事情,它的工作方式与我预期的一样,但我的期望可能就是这样,因为这就是它在1.3中的工作方式。 : - )

当我构建菜单时,我使用__('Teams')之类的内容,但我也有使用__n('Team', 'Teams', count($player->teams))之类的内容的页面。 i18n shell分别将这些提取到default.pot中,所以当我将它翻译成法语时,就像这样:

msgid "Teams"
msgstr "Équipe"

msgid "Team"
msgid_plural "Teams"
msgstr[0] "Équipe"
msgstr[1] "Équipes"

如果我拨打__('Team'),我会正确地返回'Équipe',如果我拨打__n('Team', 'Teams', $x),我会正确地返回'Équipe'或'Équipes',具体取决于{{1}的值}}。但如果我打电话给$x我就会回来

__('Teams')

即使我删除Array ( [0] => Équipe [1] => Équipes ) 部分,只留下复数定义,也是如此。

在Cake 1.3中,msgid "Teams"只会返回'Équipes'。 (不知道它在2.x中会做什么,因为我完全跳过它。)那么,这是谁的错误?

2 个答案:

答案 0 :(得分:2)

您有两个Teams条消息ID。问题是CakePHP消息文件解析器以key => value方式存储消息,其中消息ID用作密钥,导致Teams msgid_plural消息覆盖Teams来自前一个msgid的消息{1}}。

<强> https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/PoFileParser.php#L149 https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/PoFileParser.php#L172

<强> https://github.com/cakephp/cakephp/blob/3.2.8/src/I18n/Parser/MoFileParser.php#L137-L140

由于gettext似乎能够解决这个问题,我说它至少是一个缺失的功能(可能是故意的),但它甚至可能是一个错误,我无法确定(但我倾向于犯错误)。有关说明,请在at GitHub上打开一个问题。

要(暂时)解决此问题,您可以使用上下文。

答案 1 :(得分:2)

重复的邮件定义

这是有问题的:

msgid "Teams" <- same string
msgstr "Équipe"

msgid "Team"
msgid_plural "Teams" <- same string

第一个意味着你已经或者期望在应用程序代码中有__('Teams'),它希望返回一个字符串。

第二种情况是在解析po文件时创建不明确的数据。负责将po文件转换为数组格式的类是the PoFileParser,其中包含以下行:

$messages[$singular] = $translation; // <- a string
...
$messages[$key] = $plurals; // <- an array

其中$messages是用于查找翻译的数组,由翻译键索引。

因此,观察到的行为的原因是因为这段代码:

__('Teams'); 

将寻找$messages['Teams']

此代码:

__n('Team', 'Teams', 2); 

将寻找$messages['Teams'][<index>],而$messages数组将仅包含来自复数翻译的解析数据,其覆盖了&#34; singular&#34;文件中较早的字符串版本。

代码级解决方案是确保所有msgid和msgid_plural密钥都是唯一的(因为它们本质上是相同的)。

翻译定义不正确

您可能会在将来的某个时候发现像__('Teams')这样的翻译非常有问题,这取决于如何使用这个松散的词,它们是不良翻译定义的指标。

举一个例子,CakePHP曾经在烘焙输出中翻译过这个表格:

...
sprintf(__('Invalid %s', true), 'Team');
...

哪个was later changed to

__('Invalid Team', true)

因为Invalid %s的翻译可能会根据%s的内容而改变 - %s的翻译也是如此。