天天看點

Yii2 多語言配置 - i18n 國際化

原理

國際化

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
}
           

使用

  1. 簡單配置

    配置檔案如下:

    'i18n' => [ 
        'translations' => [ 
            'demo' => [ 
                'class' => 'yii\i18n\PhpMessageSource', 
                'basePath' => '@app/messages',
            ],
        ],
    ], 
               
    檔案存放位置:
    @app/messages/zh-CN/demo.php
               
    引用:
    Yii::t('demo', 'key');
               
  2. 分層級,通過檔案目錄實作

    配置檔案如下:

    'i18n' => [ 
        'translations' => [ 
            'demo*' => [ 
                'class' => 'yii\i18n\PhpMessageSource', 
                'basePath' => '@app/messages',
            ],
        ],
    ], 
               
    檔案存放位置:
    @app/messages/zh-CN/demo/common.php
               
    引用:
    Yii::t('demo/common', 'key');
               
  3. 分層級,通過配置實作

    配置檔案如下:

    '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');
               
  4. 子產品中獨立配置

    在子產品入口檔案 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');
               

繼續閱讀