必须同时配置sourcelanguage,因为yii2翻译机制以sourcelanguage为基准比对原始字符串是否需翻译;若只设language不设sourcelanguage,内置错误消息(如'page not found.')可能仍显示英文,因其键名须与@messages/zh-cn/yii.php中英文原文严格一致。

直接在 main.php 里设 'language' => 'zh-CN' 就行,这是最稳妥的全局方案。 其他方式(比如运行时赋值、入口文件覆盖)容易被后续逻辑覆盖或遗漏,尤其在表单验证、模型错误提示这类底层场景下会失效。
为什么必须同时配 sourceLanguage?
Yii2 的翻译机制依赖源语言(sourceLanguage)作为基准,用来比对原始字符串是否需要翻译。如果只改 language 而不设 sourceLanguage,部分内置错误消息(如 'Invalid data received for parameter "{param}".')可能仍显示英文——因为框架默认认为源语言是 en-US,而你的中文翻译文件没被正确匹配。
-
sourceLanguage应设为项目原始开发语言,多数中文项目填'zh-CN' - 它必须和你放在
@app/messages/zh-CN/yii.php里的键名一致(比如'Page not found.' => '页面未找到。') - 若项目最初用英文开发,才设
'en-US';但此时中文翻译文件得对应@app/messages/zh-CN/yii.php,且键必须是英文原文
i18n 组件里 translations 怎么写才不漏翻译?
光有 language 和 sourceLanguage 不够,还得让 Yii2 知道去哪里找中文翻译文件。关键在 i18n 的 translations 配置:
- 必须显式声明
'yii'类别,否则模型验证错误、路由提示等系统级消息不会走中文包:'yii' => ['class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@app/messages'] - 通配规则
'app*'可以覆盖自定义消息,但别写成'*'——它会干扰yii类别的优先级匹配 -
basePath指向的目录下,必须存在zh-CN/子目录,且里面要有yii.php文件(内容为return [...]关联数组)
动态切换语言时,Yii::$app->language 被忽略的常见原因
手动执行 Yii::$app->language = 'zh-CN' 后仍显示英文,大概率是时机问题:
- 它必须在
i18n组件初始化之后、任何Yii::t()调用之前设置,否则翻译已缓存 - 控制器里设了,但视图渲染时又触发了新组件(比如 Widget),而 Widget 内部没继承当前语言上下文
- Session 中存了语言偏好,但入口文件
web/index.php没读取并提前赋给$application->language,导致请求初期就用了默认值
最稳的做法:把语言判定逻辑提到应用启动前,在 web/index.php 里完成赋值,而不是依赖运行时修改。











