配置i18n到web.php

在config/main.php中加入以下内容。其中,language为全局语言设置;basePath的@app/common/messages等同于,项目目录下common/messages文件夹(这个文件夹需要自行创建,当然大家可以设置自定义目录,代表映射目录);sourceLanguage,即需要被转化的语言,这里选择英语为源语言;fileMap,即messages文件夹下的文件映射。

main.php部分内容

//全局语言设置
'language' => 'zh-CN',
'components' => [
    // ...
    'i18n' => [
        'translations' => [
            'app' => [
                'class' => 'yii\i18n\PhpMessageSource',
                'basePath' => '@common/messages',
                'sourceLanguage' => 'en-US',
                'fileMap' => [
                    'app' => 'app.php',
                    'app/error' => 'error.php',
                ],
            ],
        ],
   ],
],

使用yii生成i18n插件配置

  1. 在项目目录下,使用yii命令生成i18n插件配置文件。(事实上,该配置文件在使用之后,可以删除,因为,它的作用只是在生成映射文件时提供参数。)
  2. ./yii message/config @common/config/i18n.php
  3. 生成的文件为config/i18n.php,里面已经有很多默认参数。在修改参数sourcePath(需要被转化的文件夹路径,这里使用整个项目目录),messagePath(这个需要和web.php中的basePath一致),languages(转化目标语言)之后,内容如下。

i18n.php

return [
    'color' => null,
    'interactive' => true,
    'sourcePath' => '@app',
    'messagePath' => '@common/messages',
    'languages' => ['zh-CN'],
    'translator' => 'Yii::t',
    'sort' => false,
    'overwrite' => true,
    'removeUnused' => false,
    'markUnused' => true,
    'except' => [
        '.svn',
        '.git',
        '.gitignore',
        '.gitkeep',
        '.hgignore',
        '.hgkeep',
        '/messages',
        '/BaseYii.php',
    ],
    'only' => [
        '*.php',
    ],
    'format' => 'php',
    'db' => 'db',
    'sourceMessageTable' => '{{%source_message}}',
    'messageTable' => '{{%message}}',
    'catalog' => 'messages',
    'ignoreCategories' => [],
];

使用yii生成映射目录

./yii message/extract @common/config/i18n.php

使用以上命令,实际上就是按照i18n.php中给定的参数,执行扫描操作,将所有形如Yii::t('app', 'xxx')这样语句中的xxx取出,放入映射文件中。
这时,在common/messages中会有zh-CN文件夹生成,里面的app.php即为映射文件。

app.php

return [
   'Username' => '',
   'UserId' => '',
];

生成 app.php 后自行翻译到相应位置即可

使用

Yii::t('app', 'This is a english message!')

动态更改返回中英文

//BaseController
public function beforeAction($action)
{
    if (!Yii::$app->request->isOptions) {
            if (Yii::$app->request->headers->get('language')) {
                Yii::$app->language = Yii::$app->request->headers->get('language') ?: 'en-US';
            }
        }
        return parent::beforeAction($action); 
}

命名占位符

可以添加参数到翻译消息,翻译后这些参数将被对应的值替换。格式是使用大括号包围参数名,如下所示:

$username = 'Alexander';
 
echo \Yii::t('app', 'Hello, {username}!', [
 
    'username' => $username,
 
]);

位置占位符注意给参数赋值没有大括号。

$sum = 42;
 
echo \Yii::t('app', 'Balance: {0}', $sum);

高级占位符格式提示:要努力保持消息字符串有意义和避免使用太多位置参数。记住翻译者只有源字符串,所以每个占位符替换什么必须是清晰明确的。

要使用高级功能需要安装和启用 intl PHP 扩展。安装并启用这个扩展后就能够对占位符使用扩展语法。可以是默认设置的缩写形式{placeholderName, argumentType} ,也可以是允许指定格式风格的完整形式 {placeholderName, argumentType, argumentStyle} 。

完整参考请看available at ICU website。但它有点晦涩,我们在下面提供自己的参考。

数字

$sum = 42;
 
echo \Yii::t('app', 'Balance: {0, number}', $sum);
 

$sum = 42;
 
echo \Yii::t('app', 'Balance: {0, number, currency}', $sum);


你可以指定内置格式风格 (integer, currency, percent)的其中一个:

或指定自定义格式:

$sum = 42;
 
echo \Yii::t('app', 'Balance: {0, number, ,000,000000}', $sum);

日期格式参考。

echo \Yii::t('app', 'Today is {0, date}', time());
 

echo \Yii::t('app', 'Today is {0, date, short}', time());


内置格式有 (short, medium, long, full):

自定义格式:

echo \Yii::t('app', 'Today is {0, date, YYYY-MM-dd}', time());

时间格式参考。

echo \Yii::t('app', 'It is {0, time}', time());
 

echo \Yii::t('app', 'It is {0, time, short}', time());


内置格式 (short, medium, long, full):

自定义格式:

echo \Yii::t('app', 'It is {0, date, HH:mm}', time());

拼出格式参考。

echo \Yii::t('app', '{n,number} is spelled as {n, spellout}', ['n' => 42]);
 

echo \Yii::t('app', 'You are {n, ordinal} visitor here!', ['n' => 42]);


序数

将输出 "You are 42nd visitor here!"。

期间

echo \Yii::t('app', 'You are here for {n, duration} already!', ['n' => 47]);

复数将输出 "You are here for 47 sec. already!"。

不同语言的复数表现形式不同。有些规则非常复杂,所以非常方便,已提供的功能不需要指定转化规则。相反它只需要在指定的位置输入转化好的单词即可。

echo \Yii::t('app', 'There {n, plural, =0{are no cats} =1{is one cat} other{are # cats}}!', ['n'=> 0]);

在以上的复数规则参数, =0 指恰好等于零, =1 指恰好是一个,而 other 是此外的所有数字。# 将用 n 参数值替换。但不是所有语言都像英语这么简单,如俄语的例子:将输出 "There are no cats!"。

1

Здесь {n, plural, =0{котов нет} =1{есть один кот} one{# кот} few{# кота} many{# котов} other{# кота}}!

以上要提出的是 =1 精确匹配 n = 1 但 one 匹配 21 或 101 。

注意如果使用两次占位符,一次用来表示复数而另一处要用来表示数字,否则将会输出 "Inconsistent types declared for an argument: U_ARGUMENT_TYPE_MISMATCH" 错误:

1

Total {count, number} {count, plural, one{item} other{items}}.

了解你的语言要用哪个转化形式可以参考rules reference at unicode.org。

选集

可以基于关键词挑选短语,这种例子的格式指定了怎样映射关键词到短信并提供了默认短语。

echo \Yii::t('app', '{name} is {gender} and {gender, select, female{she} male{he} other{it}} loves Yii!', [
 
    'name' => 'Snoopy',
 
    'gender' => 'dog',
 
]);

在表达式中 female 和 male 都是可选值,而 other 处理那些不匹配前两者的值。大括号内的字符串是子表达式所以可以是一个字符串也可以是字符串和占位符。将输出 "Snoopy is dog and it loves Yii!".