国际化白标签PHP代码的最佳实践


best practice for internationalizing white-labeled PHP code

我有一个可以为不同客户定制的代码库。在大多数情况下,这是通过加载一个类来处理的,该类具有特定于每个客户的常量,但具有相同的类名。类名冲突是受管理的,而且很明显,一次只加载一个。

class Customer () {
    const CUST_NAME = 'Alpha Corp.';
}
class Customer () {
    const CUST_NAME = 'Beta, Inc.';
}

对于每个客户,我还希望代码国际化。因此,程序可以从特定于语言的源中绘制其显示的文本,但对于特定于客户的信息仍然是动态的。假设特定于客户的信息与i18n无关。这将文件数量从每种语言的每个客户一个减少到每种语言只有一个。期望的结果是实现类似的东西

// in separate language files:
$greeting = 'Hello. Welcome to ';
$greeting = 'Hola. Bienvenido a ';
// in front-end
$greeting = get $greeting in desired language;
echo $greeting, Customer::CUST_NAME, "'n";

我能设计出的满足这些需求的最佳解决方案是i18n类(或类族),它可以处理多个客户和/或多种语言。但是,与字符串文字或常量相比,调用方法的执行成本很高。这些方法将组合来自常量或外部源的转换,并将它们与Customer类中的值组合。(我现在只使用PHP 5.2,所以类属性/常量的heredoc细节不可用。)

class i18n_en () {
    const GREETING = 'Hello. Welcome to ';
    static public function getGreeting () {
        return self::GREETING . Customer::CUST_NAME;
    }
}

或者,我可以为"模板方法"编写一个脚本,在该脚本中,我维护类的一个带有文本占位符的模板文件。客户特定的文件是在客户创建时从这些模板生成的。根据需要生成或重新生成文件会很容易,但我又需要为每种语言的每个客户提供一个单独的文件。因此,它不能很好地满足我的需求。

当然,我不是第一个面对这个问题的人。有人能提供替代方案或最佳实践吗?由于代码的执行次数将比我创建新客户的次数多很多倍,所以我更喜欢运行时效率而不是易于维护。当然,一个好的解决方案会同时提供这两种服务。

PHP国际化有两种行之有效的方法。

最普遍的是创建巨大的语言数组,比如:

define('MSG__GREETING', 1);
$lang['en_US'] = array(MSG__GREETING => 'Hello, and welcome to ');
$lang['fr_FR'] = array(MSG__GREETING => 'Bonjour, et bienvenue à ');
$selectedLang = 'fr_FR';
echo $lang[$selectedLang][MSG__GREETING] . 'Fhloston Paradise';

不幸的是,这很快就会变得非常乏味。

我已经使用过很多次的理想方法是Linux应用程序的国际化方法:il8n,通过PHP的gettext扩展。

使用这种方法,你基本上会做这样的事情:

setenv('LANG=fr_FR');
echo _('Hello, and welcome to ') . 'Fhloston Paradise';

然后在il8n文件(称为.po)中获得每个翻译。事实上,从长远来看,维护和扩展要容易得多,尤其是因为你可以通过电子邮件将你的.po文件发送给不同的翻译人员,他们只是填补空白,就像以前一样。。。没有必要的编码技能。

以下是入门教程:http://kunststube.net/frontback/

就我个人而言,在处理国际化时,我一直使用模板,特别是Smarty-http://www.smarty.net/并创建基于语言的模板。您还可以在数据库中使用翻译键,例如带有键、语言和翻译列的表,这些列可以通过这种方式缓存,而不会调用大量方法。此外,您可以使用memcached将所有翻译方法的输出缓存在内存中。很多方法。希望其中的一些能有所帮助。