Yii2 內建強大的國際化(I18N)機制,透過訊息來源與翻譯檔案,可輕鬆實現框架核心訊息、驗證錯誤訊息、表單欄位標籤的多語系切換。本文以繁體中文(zh-TW)為例,詳細說明設定步驟與實務操作。
<?php
// config/web.php (前台) 或 config/main.php (後台/通用)
return [
'id' => 'my-app',
'language' => 'zh-TW', // 目標語言
'sourceLanguage' => 'en-US', // 原始訊息語言
// ...
];
'components' => [
'i18n' => [
'translations' => [
'yii*' => [ // 框架核心訊息
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages', // 翻譯檔存放目錄
'fileMap' => [
'yii' => 'yii.php',
'yii/error' => 'error.php',
],
],
'app*' => [ // 應用程式自訂訊息
'class' => 'yii\i18n\PhpMessageSource',
'basePath' => '@app/messages',
],
],
],
],
目錄結構:
messages/
└── zh-TW/
├── yii.php # 框架核心訊息翻譯
├── error.php # 錯誤代碼訊息翻譯
└── app.php # 應用自訂訊息
messages/zh-TW/yii.php 範例(可從 vendor/yiisoft/yii2/messages/zh-TW/yii.php 複製修改):
<?php
return [
'{attribute} cannot be blank.' => '{attribute} 不能為空。',
'{attribute} is invalid.' => '{attribute} 格式無效。',
'Verification code is incorrect.' => '驗證碼錯誤。',
// ...更多
];
在 Model 覆寫 attributeLabels() 方法,回傳屬性名稱對應的顯示標籤。
<?php
namespace app\models;
use yii\base\Model;
class ContactForm extends Model
{
public $name;
public $email;
public $subject;
public $body;
public $verifyCode;
public function rules()
{
return [
[['name', 'email', 'subject', 'body'], 'required'],
['email', 'email'],
['verifyCode', 'captcha'],
];
}
// 重點:設定屬性標籤
public function attributeLabels()
{
return [
'name' => '稱呼',
'email' => '電子郵件',
'subject' => '主旨',
'body' => '內容',
'verifyCode' => '驗證碼',
];
}
}
<?php
use yii\widgets\ActiveForm;
use yii\helpers\Html;
$form = ActiveForm::begin();
echo $form->field($model, 'name')->textInput(); // 自動產生
echo $form->field($model, 'email')->textInput(); //
echo $form->field($model, 'subject')->textInput();
echo $form->field($model, 'body')->textarea();
echo $form->field($model, 'verifyCode')->widget(\yii\captcha\Captcha::class);
echo Html::submitButton('送出', ['class' => 'btn btn-primary']);
ActiveForm::end();
<?php
// 控制器
Yii::t('app', 'Welcome, {name}!', ['name' => $user->name]);
// 視圖
echo \Yii::t('app', 'Hello {username}', ['username' => $username]);
// 指定語言(臨時切換)
echo \Yii::t('app', 'Hello', [], 'en-US');
<?php
use yii\i18n\Formatter;
$formatter = Yii::$app->formatter;
$formatter->locale = 'zh-TW'; // 設定地區
echo $formatter->asDate('2023-08-02', 'php:Y年m月d日'); // 2023年08月02日
echo $formatter->asCurrency(12345.67, 'TWD'); // NT$12,345.67
echo $formatter->asDecimal(1234567.89); // 1,234,567.89
echo $formatter->asPercent(0.1234); // 12.34%
echo $formatter->asSize(1024*1024*50); // 50 MB
大型專案建議將翻譯存入資料庫,支援後台管理介面編輯:
'i18n' => [
'translations' => [
'app*' => [
'class' => 'yii\i18n\DbMessageSource',
'sourceMessageTable' => 'i18n_source_message',
'messageTable' => 'i18n_message',
'enableCaching' => true,
'cachingDuration' => 3600,
],
],
],
執行遷移建立資料表:
php yii migrate --migrationPath=@yii/i18n/migrations/
| 現象 | 原因 | 解決 |
|---|---|---|
| 設定 language 但介面仍為英文 | 翻譯檔案路徑錯誤、檔名不符、快取未清除 | 檢查 basePath、fileMap、執行 php yii cache/flush |
| attributeLabels 不生效 | Model 未繼承 yii\base\Model、方法名拼錯 | 確認繼承關係、方法名為 attributeLabels |
| 日期格式不依 locale 顯示 | formatter->locale 未設定、ICU 資料缺失 | 安裝 intl 擴展、設定 formatter->locale |
| 複數形式翻譯錯誤 | 未使用 Yii::t 複數形式語法 | 使用 Yii::t('app', '{n, plural, one{# book} other{# books}}', ['n' => $count]) |
Yii2 I18N 機制完善且彈性:框架訊息靠 messages 目錄,表單標籤靠 attributeLabels(),動態文字靠 Yii::t(),格式化靠 Formatter。依照本文步驟設定,即可快速完成專案漢化,並為未來擴充英文、日文等語言打下堅實基礎。