Php 如何为gettext本地化加载两个mo文件

Php 如何为gettext本地化加载两个mo文件,php,mysql,gettext,Php,Mysql,Gettext,我试图解决这个问题,以加载两个mo文件。 我有两个mo文件,它们都有不同的msgid和msgstr 我的文件夹结构如下。 本地/en_US/LC_MESSAGES/lang.mo 本地/en_US/LC_消息/brand.mo 下面是我用来加载mo文件的代码 define('PROJECT_DIR', realpath('./')); define('LOCALE_DIR', PROJECT_DIR .'/locale'); define('DEFAULT_LOCALE', 'en_US');

我试图解决这个问题,以加载两个mo文件。 我有两个mo文件,它们都有不同的msgid和msgstr

我的文件夹结构如下。 本地/en_US/LC_MESSAGES/lang.mo 本地/en_US/LC_消息/brand.mo

下面是我用来加载mo文件的代码

define('PROJECT_DIR', realpath('./'));
define('LOCALE_DIR', PROJECT_DIR .'/locale');
define('DEFAULT_LOCALE', 'en_US');
$encoding = 'UTF-8';
$locale = (isset($_SESSION['lang']))? $_SESSION['lang'] : DEFAULT_LOCALE;
// gettext setup
T_setlocale(LC_MESSAGES, $locale);
// Set the text domain as 'messages'
$our_domain = 'lang';
T_bindtextdomain($our_domain, LOCALE_DIR);
T_bind_textdomain_codeset($our_domain, $encoding);
T_textdomain($our_domain);

如何在此处添加更多mo文件

您只需再次使用
bindtextdomain
textdomain
功能,即可将新的翻译文件设置为默认资源

简化它的一个好方法是创建实用函数,比如说
selectTrFile($filename)
,这将使它看起来像这样:

function selectTrFile($trFile) {
    bindtextdomain($trFile, TRANSLATION_BASE_DIR); // The constant being the path of you translations file directory
    textdomain($trFile);
}

// Now set the first file

selectTrFile('default');

// Do your stuff with this translations file

selectTrFile('anotherTranslationsResource');

// Have fun with it
您甚至可以通过将上面的函数包装到另一个自动为您切换文件的函数中来加快速度

function _f($msgid, $trFile){ // called _f to make it very short to type
    selectTrFile($trFile); // Switch the translations file
    return _($msgid); // Return the translated string
}

// Then wrap your translations filenames in short variables
$f1 = 'lang';
$f2 = 'brand';

// now you can translate Strings easily from one file or another.
_f("to be translated in file 'lang'", $f1);
_f("to be translated in file 'brand'", $f2);
如果您不知道翻译在哪个文件中,可以使用此函数代替
\u f($msgid,$trFile)

最后一个的问题是,它可能会减慢很多进程,我不知道在什么时候。您可以通过不每次更改为
'lang'
来优化它,如果字符串未被翻译或类似情况,则查看实际的字符串

编辑

我认为您不能一次加载多个翻译资源。这对于msgid的冲突来说太危险了。制作一个更大的.mo文件比加载多个文件要好

这就是为什么msgfmt确保在编译时没有冲突的MSGID。不要害怕非常大的.po/.mo文件。Mo是一种编译后的非常快速的格式

现在可能出现的问题是有一个非常笨拙的.po文件。为了避免这种情况,最好的方法是将文件分成多个部分

有两种方法可以分隔节,一种是按文件分隔,另一种是按主题分隔。如果您计划在多个文件中使用相同的翻译(如果正确使用include,这种情况应该很少发生),您可以按主题进行分隔

通常的方法是按文件分隔,并在字符串所在的位置添加注释

##
# File : /your/php/file.php
##
msgid "first String in file.php"
msgstr "first translation in file.php
.
.
.
##
# File : your/other/file.php
##
msgid "other translation"
msgstr "and then you go on"
因此,关键是,如果您正确地遵循指导原则,就不需要从单个.php文件访问多个.mo文件


有关更多信息,请参阅。

将字符串分类为不同的域和类别:

_('Foo')                                  // LC_MESSAGES/messages.mo
dgettext('brands', 'Foo')                 // LC_MESSAGES/brands.mo
dcgettext('brands', 'Foo', LC_MONETARY)   // LC_MONETARY/brands.mo

其思想是在源代码中对字符串进行分类。

当我在PHP中使用Gettext时,我常常将一个.po/.mo对与一个或多个脚本相关联,而不是相反。不过,您可以切换.mo文件,但我不记得要切换的确切功能,我将查看它并返回。使用一个mo文件,所有操作都正常。但这里我有多个不同字符串的mo,我想一次加载所有mo文件。您的答案允许同时使用两个.mo文件吗?是否允许从两个文件中获取翻译。是,但不能同时获取。每次要从另一个文件获取翻译时,都必须调用该函数。我会再次编辑以更好地解释。我理解这一点。但要求是在单独的文件中保留一些id。两个文件中都不会有重复的ID。我收到两个具有不同ID的mo。并且需要在同一页中使用两者的翻译。在任何情况下,如果有可能实现,请建议我。
locale/
    en/                    <-- language
       LC_MESSAGES/        <-- category
           messages.mo     <-- domain
           brands.mo       <-- domain
_('Foo')                                  // LC_MESSAGES/messages.mo
dgettext('brands', 'Foo')                 // LC_MESSAGES/brands.mo
dcgettext('brands', 'Foo', LC_MONETARY)   // LC_MONETARY/brands.mo