【问题标题】:best practice for internationalizing white-labeled PHP code国际化白标 PHP 代码的最佳实践
【发布时间】:2012-02-26 07:33:42
【问题描述】:

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

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

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

当然,我不是第一个遇到这个问题的人。任何人都可以提供替代方案或最佳实践吗?由于代码的执行次数比我创建新客户的次数多很多倍,因此我更喜欢运行时效率而不是易于维护。当然,一个很好的解决方案可以同时提供。

【问题讨论】:

  • 您确定一个方法调用会在该getGreeting() 方法的一千次调用中产生任何可分析的开销吗?静态字符串连接的繁琐值得衡量吗?

标签: php internationalization


【解决方案1】:

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/

【讨论】:

  • 谢谢。我一定会调查gettext。我假设这些只是我可以找到/替换占位符的文本文件,例如 [[CUST_NAME]]?此外,您还可以获得第五元素参考的加分。 :)
  • 刚刚检查...你知道如何创建你的 po 和 pot 文件吗?
  • 我没有时间处理它。不过,感谢您的兴趣。如果/何时我会发布。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 2011-11-14
    • 2010-09-14
    • 1970-01-01
    • 2010-09-13
    • 1970-01-01
    相关资源
    最近更新 更多