国际化 i18n
框架内置了一个轻量级的国际化(i18n)模块,基于 PHP 数组文件加载翻译文案,支持多语言切换、嵌套键查找、占位符替换与回退语言。
启用模块
i18n 是按需加载的可选模块。在 config/ 目录下创建 i18n.php 配置文件即可自动启用:
php
// config/i18n.php
return [
// 默认语言
'locale' => 'zh-CN',
// 回退语言:当前语言找不到翻译时使用
'fallback_locale' => 'en',
// 翻译文件根目录(默认为 basePath/app/lang)
'path' => base_path('app/lang'),
];翻译文件结构
翻译文件存放在 path 目录下,按语言分子目录,每个分组一个 PHP 文件,返回关联数组:
app/lang/
├── zh-CN/
│ ├── messages.php
│ └── validation.php
└── en/
├── messages.php
└── validation.phpphp
// app/lang/zh-CN/messages.php
return [
'welcome' => '欢迎,:name',
'common' => [
'ok' => '确定',
'cancel' => '取消',
],
];
// app/lang/en/messages.php
return [
'welcome' => 'Welcome, :name',
'common' => [
'ok' => 'OK',
'cancel' => 'Cancel',
],
];翻译调用
辅助函数(推荐)
php
// 基础翻译
echo lang('messages.welcome');
// 带占位符替换
echo lang('messages.welcome', ['name' => 'Tom']);
// 输出:欢迎,Tom
// 嵌套键(点号分隔)
echo lang('messages.common.ok');
// 输出:确定
// 指定语言
echo lang('messages.welcome', ['name' => 'Tom'], 'en');
// 输出:Welcome, Tom通过容器获取实例
php
use Lychee\i18n\I18n;
$i18n = app('i18n'); // 或 app(I18n::class)
echo $i18n->lang('messages.welcome', ['name' => 'Tom']);占位符大小写变体
除 :name 外,还支持 :NAME(全大写)和 :Name(首字母大写):
php
// messages.welcome => 'Hello, :Name'
lang('messages.welcome', ['name' => 'tom']);
// 输出:Hello, Tom切换语言
php
app('i18n')->setLocale('en');
// 获取当前语言
$locale = app('i18n')->getLocale();
// 获取回退语言
$fallback = app('i18n')->getFallbackLocale();判断翻译是否存在
php
if (app('i18n')->has('messages.welcome')) {
// ...
}has() 在当前语言或回退语言中找到即返回 true。
语言自动检测中间件
框架提供了 Lychee\i18n\I18nMiddleware,可在请求处理前自动识别并设置语言。识别优先级:
- 查询参数
?lang=en - Cookie
lang Accept-Language请求头
检测到的语言会写回 lang Cookie,便于后续请求复用。
注册中间件
在路由或控制器上通过注解挂载:
php
use Lychee\i18n\I18nMiddleware;
use Lychee\routing\Route;
#[Route('/')]
#[Middleware(I18nMiddleware::class)]
public function index()
{
return lang('messages.welcome');
}也可在中间件配置中全局注册(参见 中间件 Middleware)。
回退机制
当当前语言的翻译文件中找不到指定键时,会自动回退到 fallback_locale;若回退语言也没有,则返回键名本身:
php
// zh-CN/messages.php 中没有 'goodbye',en/messages.php 中有
lang('messages.goodbye'); // 输出 en 中的翻译
lang('messages.unknown'); // 输出 messages.unknown示例:多语言响应
php
use Lychee\http\JsonResponse;
use Lychee\routing\Route;
#[Route('/hello')]
public function hello(): JsonResponse
{
return new JsonResponse([
'message' => lang('messages.welcome', ['name' => 'Tom']),
]);
}请求 GET /hello?lang=en 时返回英文,GET /hello?lang=zh-CN 返回中文。
