代码之家  ›  专栏  ›  技术社区  ›  mojuba

在PHP中保留依赖于区域设置的字符串资源的最佳方法?

  •  2
  • mojuba  · 技术社区  · 14 年前

    假设您正在构建一个多语言web应用程序,其中所有界面文本都应移动到依赖于语言的资源中,并在需要时加载。字符串资源可能很大:假设您有数千个字符串被翻译。在窗口环境(Windows、OS X、X11)中,通常有一种由OS或一些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'!;
    ...
    

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

    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+;不能使用表达式,只能使用单个值(在您的情况下,这可能是好的,也可能不是好的);不能在双引号字符串中使用$-扩展(或者可以吗?).

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

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

    请记住简洁、优雅和性能!

    4 回复  |  直到 14 年前
        1
  •  3
  •   David Snabel-Caunt    14 年前

    Zend框架有一个名为Zend_Translate的组件,它非常有用,并且 manual page has a good write up 以不同的方式存储字符串,即使您决定不使用ZF组件。

    如果您作为开发人员维护字符串,PHP是性能最好的解决方案。如果你在一家翻译公司工作,他们很可能会期望与csv合作,并将这些信息来回发送。

    我不知道一个数组或基于常量的解决方案是否更好,但我的钱在数组上。一个快速的基准很快就会告诉你。

        2
  •  1
  •   mingos    14 年前

    gettext呢? 或者,Zend框架提供了一个真正可靠的接口来处理翻译。

        3
  •  1
  •   bkilinc    14 年前

    我使用mysql表存储所有语言字符串。这样我可以很容易地创建一个用户界面来编辑它们。

        4
  •  0
  •   mojuba    14 年前

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

    毫不奇怪的是,与globals和array方法相比,常量的加载和编译速度要快得多。但令我惊讶的是,常量的访问速度明显较慢!可能是因为这是PHP中的一种新机制,还没有完善。

    考虑到您通常加载大量的区域设置数据,然后只使用其中的一小部分,我认为最明智的方法是常量。毫不奇怪,类静态常量的性能优于全局常量。

    所以我选择方法3。我还没有测试过数据库方法,但有迹象表明,读取整个数据库表与读取同一卷的PHP源文件大致相同或更昂贵。