gettext如何处理动态内容?

Nat*_*n H 11 php gettext internationalization

在php(或者通常是gettext)中,当gettext看到变量为动态内容时,它会做什么?

我有2个案例.

1)让我说我有<?=$user1?> poked John <?=$user2?>.也许在某种语言中,单词的顺序是不同的.gettext如何处理?(不,我不是在构建facebook,这只是一个例子)

2)假设我将一些类别存储在数据库中.它们很少,但它们存储在数据库中.如果我这样做<?php echo gettext($data['name']); ?> 会怎么样?我希望翻译人员也翻译这些类别名称,但它是否必须在数据库中完成?

谢谢

Mar*_*ark 20

您最好的选择是使用spritf()函数.然后,您将使用printf表示法来处理字符串中的动态内容.这是我刚才在这里找到的一个功能,可以轻松地为您处理:

function translate()
{
    $args = func_get_args();
    $num = func_num_args();
    $args[0] = gettext($args[0]);

    if($num <= 1)
      return $args[0];

    return call_user_func_array('sprintf', $args);

}
Run Code Online (Sandbox Code Playgroud)

现在举例1,您可能希望将字符串更改为:

%s poked %s
Run Code Online (Sandbox Code Playgroud)

您将输入到translate()函数中,如下所示:

<?php echo translate('%s poked %s', $user1, $user2); ?>
Run Code Online (Sandbox Code Playgroud)

您将使用poEdit解析所有translate()函数.然后将字符串"%s poked%s"翻译成您想要的任何语言,而不修改%s字符串占位符.那些将分别由user(1)和user2的translate()函数输出替换.您可以在PHP手册中阅读有关sprintf()的更多信息,以获得更多高级用法.

问题#2.您需要创建一个poEdit可以解析的静态文件,其中包含类别名称.例如"misctranslations.php":

<?php

_('Cars');
_('Trains');
_('Airplanes');
Run Code Online (Sandbox Code Playgroud)

然后poEdit解析misctranslations.php.然后,您可以使用输出类别名称转换<?php echo gettext($data['name']); ?>

  • 案例1可以更容易处理:`<?php echo sprintf(_('%s poked%s'),$ user1,$ user2); ?>`.你不需要一个额外的功能,poedit仍然可以像其他任何一样解析字符串. (4认同)
  • 如果您正在翻译“%s poked %s”,当两个用户都标有相同的占位符时,如何交换他们的姓名?在某些语言中,主语在宾语之前。 (2认同)

Jul*_*ian 5

在 Mark 所说的基础上建立一点……上述解决方案的唯一问题是必须始终手动维护静态列表,并且如果您在所有其他字符串之前添加一个新字符串,或者您完全更改现有字符串,则软您用于翻译可能会混淆新字符串,并且您可能会丢失一些翻译。

我实际上正在写一篇关于这个的文章(时间太短,无法很快完成!)但我建议的答案是这样的:

Gettext 允许您存储字符串出现在 .po 文件内的代码中的行号。如果您完全更改字符串,.po 编辑器将知道该字符串不是新的而是旧的(感谢行号)。

我对此的解决方案是编写一个脚本来读取数据库并创建一个包含所有 gettext 字符串的静态文件。与 Mark 解决方案的最大区别在于,数据库上的主键(我们称之为 ID)与新文件中的行号相匹配。在这种情况下,如果您完全更改一个原始翻译,行仍然相同,您的翻译软件将识别字符串。

当然,那里可能有更新和更智能的 .po 编辑器,但至少如果你的编辑器给你带来了新字符串的麻烦,那么这将解决它们。

我的 2 美分。