yii2 i18n生效需两步:一是在应用配置中显式注册i18n组件并设sourcelanguage为'en-us',basepath指向的messages目录必须存在且可读;二是确保phpmessagesource翻译文件路径、category命名、键名大小写完全匹配,如yii::t('frontend/common', 'save')对应@/messages/zh-cn/frontend/common.php中return ['save'=>'保存'];,同时手动设置yii::$app->language并清除runtime缓存。

Yii2 的 i18n 组件怎么配才生效
不配 i18n 组件,Yii::t() 就只是原样返回字符串,不会翻译。核心是两件事:注册组件 + 确保消息源路径可读。
-
i18n必须在应用配置(config/web.php或config/main.php)里显式声明,不能靠默认行为 -
sourceLanguage建议写死为'en-US',避免从$_SERVER读取导致不可控 -
basePath指向的目录必须存在,且 Web 进程有读权限;常见坑是路径写成@app/messages却没建对应文件夹 - 如果用
PhpMessageSource(默认),翻译文件得是 PHP 数组格式,不是 JSON 或 YAML
Yii::t() 的 category 和 message 怎么对应翻译文件
category 不是随便起的,它直接决定 Yii 去哪个子目录下找 PHP 文件;message 是键,不是占位符模板本身。
- 调用
Yii::t('frontend/common', 'Save')→ Yii 会加载@app/messages/zh-CN/frontend/common.php - 该 PHP 文件必须返回一个数组:
return ['Save' => '保存'];,键名必须完全一致(区分大小写) - category 中的斜杠
/会被转成目录分隔符,所以frontend/common≠frontend_common - 如果 category 是
app,就查@app/messages/zh-CN/app.php;没这个文件就回退到sourceLanguage对应的内容
语言切换后翻译不更新?检查 language 和缓存
Yii 不自动根据浏览器 Accept-Language 切语言,Yii::$app->language 才是实际生效值。
- 手动设语言要写在应用启动早期,比如在
bootstrap阶段或Controller::init()里,别等到视图里才改 -
PhpMessageSource默认开启缓存,改了翻译文件要清 Yii 的 runtime 缓存(rmdir -rf runtime/cache),否则看不到效果 - 如果用了
DbMessageSource,记得确认language字段值是zh-CN这种标准格式,不是zh或cn - 调试时可临时加一行
var_dump(Yii::$app->language, Yii::$app->i18n->translate('app', 'Home', []));看当前语言和翻译结果
中文翻译里带变量怎么办:用 Yii::t() 的第三个参数
别拼接字符串,用占位符 + 参数数组,否则无法支持不同语序的语言(比如日语主宾谓)。
- 正确:
Yii::t('app', 'Hello {name}, you have {count} messages.', ['name' => $user->name, 'count' => $cnt]) - 错误:
'Hello ' . $user->name . ', you have ' . $cnt . ' messages.'—— 这种写法没法翻译成 “你好,{name},你有 {count} 条消息” - 翻译文件里对应项写成:
'Hello {name}, you have {count} messages.' => '你好 {name},你有 {count} 条消息。' - 注意:占位符大括号里不能有空格,
{ name }会失效;也不支持嵌套表达式,如{count > 1 ? 'messages' : 'message'}
Yii::t() 就静默失败——它不会报错,只会返回原始字符串。这点最容易被忽略。











