Yii2国际化与本地化支持实现指南
在开发面向多地区用户的Web应用时,国际化(I18N)和本地化(L10N)是必不可少的功能。Yii2框架内置了完善的国际化与本地化支持,开发者可以通过简单的配置和代码实现多语言切换、区域格式适配等需求。本文将详细介绍Yii2中国际化功能的实现方式。
一、核心概念区分
在开始实现前,需要先明确两个核心概念的区别:
国际化(I18N):指应用设计时考虑支持多语言、多区域的能力,核心是提供可切换的语言资源,不涉及具体的区域格式适配。
本地化(L10N):指根据用户的区域设置,调整日期、时间、货币、数字等格式的过程,是国际化在具体场景的落地。
二、基础配置
Yii2的国际化功能依赖i18n组件,首先需要在应用配置文件(通常是config/web.php)中添加组件配置:
'components' => [ 'i18n' => [ 'translations' => [ // 配置消息翻译源,支持通配符匹配 'app*' => [ 'class' => 'yiii18nPhpMessageSource', // 消息文件存放的基础目录,默认是 @app/messages 'basePath' => '@app/messages', // 指定支持的语言列表,避免无效语言请求 'forceTranslation' => true, ], ], ], // 配置应用默认语言,默认是 en-US 'language' => 'zh-CN', // 配置应用默认区域,影响日期、数字等格式 'timeZone' => 'Asia/Shanghai', ],
上述配置中,app*表示所有以app开头的消息类别都会使用该翻译源,你也可以根据业务需求自定义类别,例如app/backend*对应后台业务的翻译文件。
三、消息翻译文件创建
Yii2的消息翻译默认使用PHP数组格式的文件,文件目录结构需要按照「语言代码/消息类别.php」的规则存放。例如我们支持中文(zh-CN)和英文(en-US)两种语言,消息类别为app,则目录结构如下:
@app/ └── messages/ ├── zh-CN/ │ └── app.php └── en-US/ └── app.php
各语言文件的内容是键值对形式的翻译数组,示例如下:
中文翻译文件 @app/messages/zh-CN/app.php:
<?php
return [
'Welcome' => '欢迎',
'Login' => '登录',
'Logout' => '退出登录',
'Hello, {name}!' => '你好,{name}!',
];英文翻译文件 @app/messages/en-US/app.php:
<?php
return [
'Welcome' => 'Welcome',
'Login' => 'Login',
'Logout' => 'Logout',
'Hello, {name}!' => 'Hello, {name}!',
];四、视图与控制器中使用翻译
完成配置和翻译文件创建后,就可以在代码中使用Yii::t()方法进行消息翻译了,该方法的第一个参数是消息类别,第二个参数是待翻译的原始字符串,第三个参数是替换参数(可选)。
1. 视图中使用
在视图文件中直接调用翻译方法即可:
<?php
use yiihelpersHtml;
?>
<div class="site-index">
<h1><?= Yii::t('app', 'Welcome') ?></h1>
<p><?= Yii::t('app', 'Hello, {name}!', ['name' => Yii::$app->user->identity->username]) ?></p>
<?= Html::a(Yii::t('app', 'Logout'), ['site/logout'], ['data-method' => 'post']) ?>
</div>2. 控制器中使用
控制器中同样可以调用翻译方法,例如返回提示信息:
public function actionLogin()
{
if (Yii::$app->request->isPost) {
// 登录逻辑处理
if ($loginSuccess) {
Yii::$app->session->setFlash('success', Yii::t('app', 'Login successful'));
} else {
Yii::$app->session->setFlash('error', Yii::t('app', 'Login failed, please try again'));
}
}
}五、动态切换语言
实际应用中通常需要允许用户手动切换语言,实现方式是通过设置Yii::$app->language并持久化保存用户的选择,例如使用Cookie或者数据库存储用户偏好语言。
以下是语言切换动作的示例:
public function actionSwitchLanguage($lang)
{
// 限制仅允许配置中支持的语言
$supportedLanguages = ['zh-CN', 'en-US'];
if (in_array($lang, $supportedLanguages)) {
// 设置当前应用语言
Yii::$app->language = $lang;
// 将语言保存到Cookie,有效期30天
$cookie = new yiiwebCookie([
'name' => 'language',
'value' => $lang,
'expire' => time() + 30 * 24 * 3600,
]);
Yii::$app->response->cookies->add($cookie);
}
return $this->redirect(Yii::$app->request->referrer ?: Yii::$app->homeUrl);
}为了让用户下次访问时自动应用保存的语言,可以在应用启动阶段读取Cookie并初始化语言,例如在config/web.php的bootstrap中添加初始化逻辑:
'bootstrap' => [
function () {
$cookies = Yii::$app->request->cookies;
if (isset($cookies['language'])) {
$lang = $cookies['language']->value;
$supportedLanguages = ['zh-CN', 'en-US'];
if (in_array($lang, $supportedLanguages)) {
Yii::$app->language = $lang;
}
}
},
'log',
],六、本地化格式适配
除了文本翻译,Yii2还提供了本地化相关的辅助类,用于处理日期、时间、数字、货币等格式的适配,这些类会根据当前的language和timeZone配置自动调整格式。
1. 日期时间格式化
使用yiii18nFormatter类格式化日期时间:
$formatter = Yii::$app->formatter; // 输出格式会根据当前语言自动调整,中文环境下为 2024年5月20日 echo $formatter->asDate(time()); // 输出格式为中文环境下为 2024年5月20日 14:30:00 echo $formatter->asDatetime(time());
2. 数字与货币格式化
$formatter = Yii::$app->formatter; // 数字格式化,中文环境下使用千分位分隔符 echo $formatter->asInteger(1234567); // 输出 1,234,567 或根据区域调整 // 货币格式化,中文环境下人民币显示为 ¥1,234.56 echo $formatter->asCurrency(1234.56, 'CNY');
七、常见问题与注意事项
翻译文件的缓存:Yii2默认会缓存翻译文件,修改翻译文件后需要清除缓存才能生效,可以删除
runtime/cache目录下的缓存文件,或者配置cache组件禁用翻译缓存。消息类别的命名:建议按照业务模块划分消息类别,例如
app/backend、app/frontend,避免单个翻译文件过大难以维护。未翻译字符串的处理:如果
forceTranslation设置为false,当找不到对应翻译时,会直接返回原始字符串;设置为true时,即使找不到翻译也会标记该字符串需要翻译,方便后续补充。
通过以上步骤,就可以在Yii2应用中完整实现国际化与本地化支持,满足多地区用户的使用需求。如果需要扩展更多语言,只需要按照相同规则添加对应的翻译文件和配置即可。