【问题标题】:PHP gettext reverse translatePHP gettext 反向翻译
【发布时间】:2012-08-28 00:21:08
【问题描述】:

我的问题很简单,我使用 gettext 来翻译 URL,因此我只有 url 字符串的翻译版本。

我想知道是否有一种简单的方法可以从翻译后的字符串中获取基本字符串?

我的想法是在每次使用 _u($string) 函数时自动将翻译后的名称添加到数据库中,并使用基本字符串为其命名。

我目前拥有的:

function _u($string)
{
    if (empty($string))
        return '';
    else
        return dgettext('Urls', $string);
}

我在想什么(伪代码):

function _u($string)
{
    if (empty($string))
        return '';

    $translation = dgettext('Urls', $string);

    MySQL REPLACE INTO ... base = $string, translation = $translation; (translation = primary key)

    return $translation;
}

function url_base($translation)
{
    $row = SELECT ... FROM ... translation = $translation;

    return $base;
}

虽然这似乎不是最好的方法,而且如果在生产中我删除了REPLACE 部分,那么我可能会忘记生产中的一两个我可能没有去过的链接。

编辑:我主要寻找的是 gettext 的解析部分。我不需要错过任何可能的 URL,因此如果您有其他解决方案,则需要有一个解析器(基于我正在寻找的内容)。

EDIT2:刚刚添加了另一个难度。我们必须在任何翻译中找到 URL 并将其放回“基本”翻译中,以便系统解析基本语言中的 URL。

【问题讨论】:

    标签: php gettext


    【解决方案1】:

    实际上,我能想到的最直接的方法是通过调用 msgunfmt 实用程序来解码用于翻译的 .mo 文件。

    一旦你有了明文数据库,你就可以将它保存在任何其他类型的数据库中,然后就可以进行反向搜索了。

    但也许更好的是,您可以创建额外的域(“ReverseUrlsIT”),将翻译后的 URL 存储为键,将基值存储为值(前提是映射完全是双向的,即!)。

    此时,您可以使用dgettext 从已翻译字符串中恢复基本字符串,前提是您知道已翻译字符串的语言。

    更新

    这是使用 gettext 的要点,如果我会随时放弃它 我可以找到另一个可以提供帮助的解析器/库/工具

    gettext 系列函数,说到底,不过是一个密钥库数据库系统,带有(也许)一个比printf 更强大的解析器,用于处理复数和形容词/名词倒置(英语中的violin virtuoso变成意大利语中的virtuoso di violino)。

    以增加数据库复杂性(和负载)为代价,您可以利用手头的任何持久层构建密钥库(毕竟gettext 是基于文件的):

    TABLE LanguageDomain
    {
        PRIMARY KEY ldId;
        varchar(?)  ldValue;
    }
    # e.g.
    # 39   it_IT
    # 44   en_US
    # 01   us_US
    
    TABLE Shorthand
    {
        PRIMARY KEY shId;
        varchar(?)  shValue;
    }
    
    # e.g.
    # 1    CAMERA
    # 2    BED
    
    TABLE Translation
    {
        KEY t_ldId,
            t_shId;
        varchar(?)  t_Value;   // Or one value for singular form, one for plural...
    }
    
    # e.g.
    # 44    1    Camera
    # 39    1    Macchina fotografica
    # 01    1    Camera
    # 44    1    Bed
    # 39    1    Letto
    # 01    1    Bed
    # 01  137    Behavior
    # 44  137    Behaviour     # "American and English have many things in common..."
    # 01  979    Cookie
    # 44  979    Biscuit       " "...except of course the language" (O. Wilde)
    
    function translate($string, $arguments = array())
    {
        GLOBAL $languageDomain;
        // First recover main string
        SELECT t_Value FROM Translation AS t
            LEFT JOIN LanguageDomain AS l ON (t.ldId = l.ldId AND l.ldValue = :LangDom)
            LEFT JOIN Shorthand      AS s ON (t.t_shId = s.shId AND s.shValue=:String);
        // 
        if (empty($arguments))
            return $Result;
        // Now run replacement of arguments - if any
        $replacements = array();
        foreach($arguments as $n => $argument)
            $replacements["\${$n}"] = translate($argument);
        // Now replace '$1' with translation of first argument, etc.
        return str_replace(array_keys($replacements), array_values($replacements), $Result);
    }
    

    这将允许您轻松地再添加一个languageDomain,甚至可以运行查询,例如“哪些英文术语还没有被翻译成德文?” (即,当LEFT JOINing Translation 表的子集具有英语域 Id 与子集具有德语域 Id 时,具有 NULL 值)。

    此系统可与 POfile 互操作,如果您需要将翻译外包给使用行业标准工具的人,这一点很重要。但是您可以轻松地将查询直接输出为 TMX 格式,从而消除重复(在某些情况下,这可能会真正降低您的翻译成本 - 一些服务对“奇怪”格式(如 Excel)的输入多收费,或者会因“重复数据删除”而多收费或将按原件一样对每份副本收费)。

    <?xml version="1.0" ?>
    <tmx version="1.4">
            <header
                    creationtool="MySQLgetText"
                    creationtoolversion="0.1-20120827"
                    datatype="PlainText"
                    segtype="sentence"
                    adminlang="en-us"
                    srclang="EN"
                    o-tmf="ABCTransMem">
            </header>
            <body>
                    <tu tuid="BED" datatype="plaintext">
                            <tuv xml:lang="en">
                                    <seg>bed</seg>
                            </tuv>
                            <tuv xml:lang="it">
                                    <seg>letto</seg>
                            </tuv>
                    </tu>
                    <tu tuid="CAMERA" datatype="plaintext">
                            <tuv xml:lang="en">
                                    <seg>camera</seg>
                            </tuv>
                            <tuv xml:lang="it">
                                    <seg>macchina fotografica</seg>
                            </tuv>
                    </tu>
            </body>
    </tmx>
    

    【讨论】:

    • 为此使用 gettext 感觉倒退了。将 URL 简单地存储在数据库中可能会更容易、更直接。
    • 确实感觉落后了,尽管当我真的不需要忘记单个 URL 时,诸如 POEdit 之类的工具确实很有帮助。这是使用 gettext 的要点,如果我能找到另一个可以提供帮助的解析器/库/工具,我会随时放弃它。
    • @Iserni 这几乎是我在帖子中的第一个想法,我在上一条评论中主要谈到的是,我在 gettext 中最需要的是它的工具,比如 xgettext或 POEdit 用于解析文件并自动查找每个输入,因为我们目前正在将 i18n 添加到已经存在的系统中,并且有大约数千个链接模式,我们不能因为人为错误而忘记它们中的任何一个。这就是我考虑 POEdit 的原因,它是 PHP 解析器。
    • 另外,在我的项目中,我们有 2 个域,主域和 URL 域使用 2 个不同的函数(__ 双下划线和 u)选择不同的域。 (_ 选择默认值,_u URLs 之一)。
    • 我想知道我是否可以只使用 POEdit 并找到一种方法将 po 文件导入数据库并手动创建翻译工具?我不介意做更多的开发,只是我不知道如何解析 PO 文件。
    猜你喜欢
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    相关资源
    最近更新 更多