如何使用 gettext 翻译来自 MySQL 的数据?

How to translate data from MySQL with gettext?

我想使用 gettext php 翻译来自 MySQL 的字符串。 例如

$string = $db->prepare('SELECT * FROM `cities`');
$string->execute();
$value = $string->fetch(PDO::FETCH_ASSOC);

foreach($value as $k => $v) {
  $array[$v['id']] = _($v['name']);
}

这就是 _($v['name']) 我想使用 gettext

msgid "Some City"
msgstr "Some City Other Lang"

但是这个方法不行。我想要另一个解决方案

does not work

这意味着(如果我错了请纠正我)字符串提取器在解析源代码时无法找到要翻译的文本,甚至可能会抛出错误消息。这是预料之中的,因为您的字符串根本不在源代码中——它们在一个遥不可及的关系数据库中。

最基本的问题当然是 gettext 不是为那样工作而设计的。

我有时使用以下方法解决这个用例:

  1. 编写一个帮助脚本从数据库中获取字符串并将它们转储到常规 PHP 文件中,如下所示:

    <?php // db-strings.php
    // Autogenerated file, do not edit
    _('Bar');
    _('Foo');
    

    这个自动生成的文件不是用来执行的。它仅供 Poedit 或您将使用的任何提取器使用。帮助脚本类似于:

    <?php // dump-db-strings.php
    
    $fp = fopen('db-strings.php', 'wb');
    fwrite($fp, "<?php\n");
    fwrite($fp, "// Autogenerated file, do not edit\n");
    
    /** @var PDO $db*/
    $stmt = $db->prepare('
        SELECT name AS text
        FROM cities
        UNION
        SELECT some_other_column AS text
        FROM some_other_table
        ORDER BY text
    ');
    $stmt->execute();
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        fwrite($fp, sprintf("_('%s');\n", addcslashes($row['text'])));
    }
    fclose($fp);
    
  2. 将帮助程序脚本 (dump-db-strings.php) 添加到您的构建系统,因此 db-strings.php 保持更新。

  3. 创建一个自定义函数作为 gettext 包装器,这样您就不会再收到提取器错误消息,例如:

    // Untested!
    function _db($string) {
        return ${'_'}($string);
    }
    
    foreach($value as $k => $v) {
        $array[$v['id']] = _db($v['name']);
    }
    

现在,当您启动 Poedit 时,它会扫描 db-strings.php,它会找到实际的字符串,然后将其包含在 *.po 目录中。在运行时,_db($v['name']) 将执行为例如_db('Foo') 和 gettext 已经在 *.mo 编译资源中找到 Foo

请注意,此方法主要用于您控制的字符串(即它们是只有开发人员更新的固定文本),这确实有意义,因为您还需要获得实际的翻译。如果你的文本是用户自己生成的,没有你的干预,你最好找一个gettext的替代方法。