在PHP中保留依赖于语言环境的字符串资源的最佳方法?

时间:2010-10-30 18:49:53

标签: php internationalization

假设您正在构建一个多语言Web应用程序,其中应将所有界面文本移动到与语言相关的资源并在需要时加载。字符串资源可能很大:比如你已经翻译了几千个字符串。在窗口环境(Windows,OS X,X11)中,您通常会有操作系统或某些API提供的机制来执行此操作,它们通常称为字符串资源。那么PHP呢?

请记住,在这里必须认真考虑性能,因为PHP会根据每个用户请求编译并执行所有模块。

我可以想到几种可行的方法。但首先,我将有一个全局变量$ LANGUAGE,可以设置为'en','de','fr'等。我将使用此变量为每个请求包含一个特定于语言的模块如

require_once "lang-$LANGUAGE.inc.php"

因此,一些可能的解决方案包括:

(1)在每个语言模块中将所有字符串定义为全局变量,例如

$str_signin = 'Sign in';
$str_welcome_user = 'Welcome, %s'!;
...

非技术人员(翻译人员)非常简单,易于阅读且相对容易处理。虽然有一些全球空间污染会使你的全局变量查找速度变慢。

(2)相同但定义为一个巨大的数组,例如

$str['signin'] = 'Sign in';
$str['welcome_user'] = 'Welcome, %s'!;
...

在主代码中可读性较差,可用性较低(涉及更多类型)也会使代码更加混乱。这会慢一些,因为这些不是简单的赋值,而是assoc。数组赋值:与(1)相比,这里将为VM执行更多指令。

(3)PHP 5.3+:定义为常量,可能在类或命名空间中

class str {
    const signin = 'Sign in';
    const welcome_user = 'Welcome, %s'!;
    const signin_to_a = self::signin . ' to area A'; // can't do this!
    ...
}

...并将它们用作str :: signin等。很好,我最喜欢这个,虽然也有一些小缺点:仅限PHP 5.3+;不能使用表达式,只能使用单个值(在您的情况下可能会或可能不会);不能在双引号字符串中使用$ -expansion(或者你可以吗?)。

(4)数据库:将所有内容放入表中并通过某些ID检索,例如: str_get(STR_SIGNIN)。丑陋,缓慢,需要将代码中的ID与数据库ID同步,但是当您的所有页面需要的只是几个字符串时,无需加载所有内容。老实说不能说这是不是一个好的解决方案。

还有其他建议吗?还有,对这些的想法?

请注意简洁,优雅和表现!

4 个答案:

答案 0 :(得分:2)

Zend Framework有一个名为Zend_Translate的组件,即使您决定不使用ZF组件,它也可以用于存储字符串的不同方式manual page has a good write up

如果您作为开发人员维护字符串,那么PHP是性能最佳且最佳的解决方案。如果您正在与翻译公司合作,那么他们可能希望使用CSV并来回发送这些内容。

我不知道基于阵列或基于常数的解决方案是否更好,但我的钱是在阵列上。快速基准将很快告诉你。

答案 1 :(得分:1)

gettext怎么样? 或者,Zend Framework提供了一个非常可靠的界面来处理翻译。

答案 2 :(得分:1)

我使用mysql表来存储所有语言字符串。这样我就可以轻松创建用户界面来编辑它们。 我将与对象相关的所有语言字符串作为关联数组(在ADODB中使用GetAssoc函数)。我使用Pear :: Cache Class缓存assoc数组,所以下次我将简单地检索这个缓存的数组(没有数据库查询)。到目前为止,这对我来说是最好的解决方案。这可以使用不同的缓存技术进行优化。

答案 3 :(得分:0)

我为前三种方法做了简单的基准测试。我创建了具有10,000个字符串分配的模块,并分别测量了加载/编译时间以及访问时间。

与globals和array方法相比,加载和编译的常量要快得多,这并不奇怪。让我感到惊讶的是,常数的访问速度明显变慢了!可能是因为它是PHP中的一种新机制,尚未完善。

此外,事实证明,庞大的数组编译速度更快(实际上数组(...)构造甚至比all-globals方法更快),但是数组访问更加昂贵。

考虑到你经常加载大量的语言环境数据,然后只使用它的一小部分,我认为最合理的方法是常量。毫不奇怪,类静态常量的性能优于全局常量。

所以我会选择方法3.我没有测试数据库方法,但有些建议读取整个数据库表与读取相同卷的PHP源大致相同或更昂贵。