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

时间:2012-02-03 17:25:58

标签: php internationalization

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

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;
    }
}

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

当然,我不是第一个面对这个问题的人。有人可以提供替代品或最佳做法吗?由于代码执行的次数比我创建新客户的次数多,因此我更喜欢运行时效率以便于维护。当然,一个很好的解决方案将提供两者。

2 个答案:

答案 0 :(得分:5)

有两种经过验证的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's gettext extension

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

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

然后在il8n文件(称为.po)中进行每次翻译。从长远来看,维护和扩展实际上要容易得多,特别是因为您可以将.po文件通过电子邮件发送给各种翻译人员,他们只需填写空白,因为它不需要编码技能。

以下是帮助您入门的教程:http://kunststube.net/frontback/

答案 1 :(得分:1)

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