原理
國際化
i18n
是
Yii2
的核心元件,應用
bootstrap
時
i18n
就會被執行個體化。
// yii2/base/Application.php
public function coreComponents()
{
return [
'log' => ['class' => 'yii\log\Dispatcher'],
'view' => ['class' => 'yii\web\View'],
'formatter' => ['class' => 'yii\i18n\Formatter'],
'i18n' => ['class' => 'yii\i18n\I18N'],
'mailer' => ['class' => 'yii\swiftmailer\Mailer'],
'urlManager' => ['class' => 'yii\web\UrlManager'],
'assetManager' => ['class' => 'yii\web\AssetManager'],
'security' => ['class' => 'yii\base\Security'],
];
}
預設情況
i18n
會把實作交給
yii\i18n\PhpMessageSource
類,這也是項目中最常用的方式。在不修改應用配置的情況下,隻需要将多語言的 php 檔案放到
@app/messages
目錄下即可。如
zh-CN
中文配置
@app/messages/zh-CN/app.php
,檔案名必須為
app.php
。
除此外還有
yii\i18n\GettextMessageSource
和
yii\i18n\DbMessageSource
可用。
// yii2/i18n/I18N.php
public function init()
{
parent::init();
if (!isset($this->translations['yii']) && !isset($this->translations['yii*'])) {
$this->translations['yii'] = [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => 'en-US',
'basePath' => '@yii/messages',
];
}
if (!isset($this->translations['app']) && !isset($this->translations['app*'])) {
$this->translations['app'] = [
'class' => 'yii\i18n\PhpMessageSource',
'sourceLanguage' => Yii::$app->sourceLanguage,
'basePath' => '@app/messages',
];
}
}
如何配置,如何使用?關鍵要了解
i18n
是如何根據配置檔案加載多語言檔案的。
// yii2/i18n/I18N.php
public function getMessageSource($category)
{
// 判斷 $category 在配置中是否存在
// 1. 先進行完全比對
// 2. 再比對結尾帶 * 的配置
// 3. 最後直接引用 * 配置
// 如果某步成功,就把任務交給 PhpMessageSource,
// 并将 $category 傳遞給 PhpMessageSource
}
// yii2/i18n/PhpMessageSource.php
protected function getMessageFilePath($category, $language)
{
// PhpMessageSource 關鍵任務是找到多語言檔案的路徑
// 根據 $category 擷取多語言檔案的路徑
// 1. 先從 fileMap 配置中擷取路徑
// 2. 再用 $category 拼接路徑
// loadMessages() 方法根據路徑加載多語言資料傳回 I18N
}
使用
-
簡單配置
配置檔案如下:
檔案存放位置:'i18n' => [ 'translations' => [ 'demo' => [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@app/messages', ], ], ],
引用:@app/messages/zh-CN/demo.php
Yii::t('demo', 'key');
-
分層級,通過檔案目錄實作
配置檔案如下:
檔案存放位置:'i18n' => [ 'translations' => [ 'demo*' => [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@app/messages', ], ], ],
引用:@app/messages/zh-CN/demo/common.php
Yii::t('demo/common', 'key');
-
分層級,通過配置實作
配置檔案如下:
檔案存放位置:'i18n' => [ 'translations' => [ 'demo*' => [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@app/messages', 'fileMap' => [ // 檔案名應該與鍵名對應,即 common.php // 此處隻是為了說明問題 'demo/common' => 'main.php' ] ], ], ],
引用:@app/messages/zh-CN/main.php
Yii::t('demo/common', 'key');
-
子產品中獨立配置
在子產品入口檔案 Module.php 中,增加如下代碼
多語言檔案放在子產品的public function init() { parent::init(); if ( !isset(Yii::$app->get('i18n')->translations['demo*']) ) { Yii::$app->get('i18n')->translations['demo*'] = [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => __DIR__ . '/messages', 'fileMap' => [ 'demo/common' => 'common.php', ], ]; } }
./messages/
目錄下。
引用:
Yii::t('demo/common', 'key');