必须在应用初始化前设置语言,否则组件已固化默认语言;配置i18n组件、创建zh-cn/en-us语言包、设默认语言、在web/index.php中动态赋值$application->language、添加校验的language动作、视图中用yii::t()和动态链接切换。

要在Yii2.0.48中让网站支持中文、英文等多语言显示,并能通过链接一键切换,必须确保语言设置在应用初始化前完成,否则视图、验证器、日期格式器等组件已按默认语言固化,后续修改完全无效。
配置i18n组件与语言包路径
打开 common/config/main.php(高级模板)或 frontend/config/main.php(基础模板),在 'components' 数组内添加 'i18n' 配置:
'i18n' => [ 'translations' => [ 'app*' => [ 'class' => 'yii\i18n\PhpMessageSource', 'basePath' => '@app/messages', 'fileMap' => [ 'app' => 'app.php', 'app/error' => 'error.php', ], ], ],],
注意:这里用 app* 表示匹配所有以 app 开头的翻译类别,比单写 app 更灵活;【basePath 必须是 @app/messages,不能漏掉 @ 符号,否则 Yii 找不到目录】。
创建语言文件目录与内容
在项目根目录下创建 messages 文件夹(若使用 @app/messages 路径),再分别建两个子目录:zh-CN 和 en-US。
在 messages/zh-CN/ 下新建 app.php,内容为纯返回数组:
<?php return [ 'Home' => '首页', 'About' => '关于', 'Login' => '登录', 'Hello' => '你好',];
在 messages/en-US/ 下新建同名 app.php,内容为:
<?php return [ 'Home' => 'Home', 'About' => 'About', 'Login' => 'Login', 'Hello' => 'Hello',];
文件名和目录名必须严格区分大小写,zh-CN 不能写成 zh_cn 或 ZH-CN,否则 Yii 不识别。
设置默认语言并注入运行时语言
第一步:在 common/config/main.php 中添加全局默认语言:
'language' => 'zh-CN',
第二步:最关键的一步——修改入口文件 web/index.php,把语言设置放在 $application->run() 之前:
$application = new yii\web\Application($config);$language = \Yii::$app->request->cookies->get('lang') ? \Yii::$app->request->cookies->get('lang')->value : 'zh-CN';$application->language = $language;$application->run();
这一步不可跳过。如果只在控制器里改 Yii::$app->language,Formatter 已初始化完毕,日期、数字格式仍按旧语言输出,页面文字却变了,会造成严重不一致。
编写语言切换控制器动作
在 frontend/controllers/SiteController.php(或对应模块控制器)中添加:
public function actionLanguage($lang){ if (in_array($lang, ['zh-CN', 'en-US'])) { $cookies = \Yii::$app->response->cookies; $cookies->add(new \yii\web\Cookie([ 'name' => 'lang', 'value' => $lang, 'expire' => time() + 3600 * 24 * 30, ])); } $this->goBack(\Yii::$app->request->headers['Referer'] ?: \Yii::$app->homeUrl);}
注意:必须校验 $lang 值是否合法,防止任意字符串注入 cookie;【Referer 头可能为空,需提供 fallback 地址,否则 goBack 会报错】。
在视图中添加切换链接并调用翻译
方法一:直接写死链接(适合简单项目)
= \Yii::t('app', 'Home') ?>@#@#@#@#@#@#@#@#@#@0@#@#@#@#@#@#@#@#@#@1
方法二:动态生成(推荐)
$langs = [ 'zh-CN' => \Yii::t('app', 'Chinese'), 'en-US' => \Yii::t('app', 'English'),];foreach ($langs as $code => $label) { echo \yii\helpers\Html::a($label, ['site/language', 'lang' => $code]);}
所有内部 URL 必须显式传入 'lang' => Yii::$app->language,否则 Url::to() 完全不感知语言上下文,生成的链接永远不含语言前缀。











