Php Yii:多语言网站-最佳实践

Php Yii:多语言网站-最佳实践,php,internationalization,yii,Php,Internationalization,Yii,我发现Yii框架很棒,用YiC外壳创建的示例网站是一个很好的起点。。。然而,不幸的是,它没有涵盖多语言网站的主题。这些文档涵盖了翻译短信的主题,但没有保留多语言内容 我即将开始在一个网站,需要在至少两种语言的工作,我想知道什么是最好的方式来保持这方面的内容。。。 问题是内容与常见元素(如嵌入式视频文件)广泛混合 我需要避免重复那些公共空间。。。到目前为止,我曾经有一个包含文本的数组(通常不超过1-2个短段落),然后视图文件只是从数组中呈现文本 现在,我希望避免将其保存在数组中(在放置双引号“”时

我发现Yii框架很棒,用YiC外壳创建的示例网站是一个很好的起点。。。然而,不幸的是,它没有涵盖多语言网站的主题。这些文档涵盖了翻译短信的主题,但没有保留多语言内容

我即将开始在一个网站,需要在至少两种语言的工作,我想知道什么是最好的方式来保持这方面的内容。。。 问题是内容与常见元素(如嵌入式视频文件)广泛混合

我需要避免重复那些公共空间。。。到目前为止,我曾经有一个包含文本的数组(通常不超过1-2个短段落),然后视图文件只是从数组中呈现文本

现在,我希望避免将其保存在数组中(在放置双引号“”时需要注意这一点,并且通常不方便…)

那么,保存这些短段落的最佳方式是什么?我是否应该将它们保存在DB-like(id | msg | id | language | content)中,然后按msg | id&language选择它们?这仍然需要我创建一些msg_id并将它们嵌入到视图文件中

是否有Yii有一些解决方案的推荐范例

谢谢,
m

Yii应用程序默认使用Yii::t()方法翻译文本消息,消息源有3种不同类型:

  • :翻译作为键值对存储在PHP数组中
  • :翻译存储为GNU Gettext文件。(采购订单文件)
  • :消息翻译存储在数据库表中
  • 如果我没有误解的话,您正在使用经典数组进行翻译。我建议您使用带有Yii的GetText和PO文件进行翻译操作


    你可以在这里找到很多关于翻译和i18n与yii的信息。

    我想这里关心的是如何翻译页面上的静态文本/消息,yii使用yii:t()很好地解决了这个问题,Edigu的答案就是这样

    我查看了flexicams上关于在数据库中翻译动态内容的帖子,最终这将是解决静态文本/消息问题后的下一个帖子,这是使用Yii行为的一个非常好的方法。不确定FlexicaCMS的作者是否过于雄心勃勃地支持这样的翻译,因为这会使内容翻译成为一件无忧的事情——真的很棒


    他们没有提到的一件事是翻译页面的url。例如,your.site.com/fr/translated_article_title.html。我的意思是url中必须有/language\u id/part,这样它才能帮助SEO。

    Gettext易于翻译,但默认的PHP实现不是线程安全的。因此,Yii使用自己的解包,与php数组相比,大大增加了处理时间

    因为我正在建立一个高流量、高交易量的网站,所以性能受到的影响是不可接受的。此外,通过使用APC,我们可以缓存PHP翻译,从而进一步提高性能

    因此,我的方法是使用PHP数组,但为了便于翻译,将翻译保存在DB中,在翻译更改时生成所需的文件

    DB与此类似:

    TABLE Message            // stores source language, updated by script
     id INT UNSIGNED
     category VARCHAR(20)         // first argument to Yii::t()
     key TEXT                     // second argument to Yii::t()
     occurences TINYINT UNSIGNED  // number of times found in sources
    
    TABLE MessageTranslation // stores target language, translated by human  
     id INT UNSIGNED
     language VARCHAR(3)          // ISO 639-1 or 639-3, as used by Yii
     messageId INT UNSIGNED       // foreign key on Message table
     value TEXT
     version VARCHAR(15)
     creationTime TIMESTAMP DEFAULT NOW()
     lastModifiedTime TIMESTAMP DEFAULT NULL
     lastModifiedUserId INT UNSIGNED
    
    然后,我修改了CLI工具yiic'message'命令,将收集的字符串转储到数据库中

    一旦进入数据库,就可以设置一个简单的CMS,为翻译人员提供一种简单的翻译方法,同时提供版本控制信息、恢复到旧版本、检查翻译人员的质量等

    另一个脚本,也是从YIC修改的,然后获取DB信息并将其编译成PHP数组。基本上是每种语言的两个表的连接,然后使用“Message.”“key”和“MessageTranslation”构建一个数组。“value”作为(还有什么?)key=>value。。。正在保存到由语言指定的文件夹中的“邮件”“类别”中名为的文件

    Yii CPhpMessageSource会正常加载生成的文件

    对于图像,这非常简单,只需将它们放在具有适当语言的文件夹中,并在链接时获取应用程序语言即可

    <img src="/images/<?php echo Yii::app()->language; ?>/help_button.png">
    
    语言;?>/帮助按钮.png“>
    

    请注意,在现实生活中,我编写了一个小的helper方法来从语言字符串中去掉国家名,“en_us”应该是“en”。

    在Yii1和Yii2中yii\i18n\GettextMessageSource无论如何都不使用yii perfect缓存引擎(查看源代码)以增强PO或MO文件的加载。不建议使用php纯代码(包括yii\i18n\GettextMessageSource)加载这些文件(比php数组idx慢得多):

    然而,php gettext-ext for MO文件比translation php数组快一些,因为它使用缓存,但缺点是:MO中的每个更改都需要重新启动服务器

    我认为最好的解决方案是在您自己的代码库中扩展yii\i18n\GettextMessageSource,并将缓存功能添加到GettextMessageSource以增强其性能,并将扩展版本用作组件

    protected function loadMessages($category, $language);
    

    只是不要在每次加载时检查MO修改日期以与缓存进行比较,而是在MO或PO文件更改时清除缓存(可以是计划).

    GetText IMO的问题是它们很难维护和保持更新,而且您可能会遇到原子问题。我的首选方法是数据库,这样您就可以动态更新消息。如果您真的渴望速度,GetText会更快,否则DB就是最好的选择。注意:我建议不要使用没有缓存的GettextMessageSource。纯PHP GetText性能mance比php数组慢很多(Yi2本身使用php数组),因为它重复读取文件,但是使用php gettext扩展(与gettext纯php代码相比)比php数组快一些,但是使用php ext需要为每次更改重新启动服务器。