PHP gettext反向翻译

时间:2012-08-24 21:00:13

标签: php gettext

我的问题很简单,我使用gettext来翻译网址,因此我只有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。

1 个答案:

答案 0 :(得分:4)

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

获得明文数据库后,将其保存在任何其他类型的数据库中,然后就可以进行反向搜索。

但也许更好,您可以创建其他域(“ReverseUrlsIT”),在其中将转换后的URL存储为键,将基数存储为值(前提是映射完全是双向的,即!)。

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

<强>更新

  

这是使用gettext的要点,我会随时删除它   我可以找到另一个可以帮助解决

的解析器/库/工具

毕竟,gettext函数系列不仅仅是一个密钥库数据库系统,它具有(可能)比printf更强大的解析器来处理复数形式和形容词/名词倒置(英语中的小提琴演奏家在意大利语中成为 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 JOIN Translation表的子集与英语域ID以及具有德语域ID的子集时,具有NULL值。

此系统可与POfiles互操作,如果您需要使用交易的标准工具将翻译外包给某人,这一点非常重要。但是您可以轻松地将查询直接输出到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>