laravel 多语言需配置 config/app.php 的 locale 和 fallback_locale,语言文件置于 resources/lang/zh_cn/messages.php 并用 :key 占位符,切换语言推荐中间件统一设置 app::setlocale()。

怎么在 Laravel 里启用多语言(i18n)基础支持
Laravel 默认已内置多语言支持,不需要额外装包,但必须手动启用——关键动作是配置 config/app.php 中的 locale 和 fallback_locale,否则 __() 函数会静默回退到英文或报错。
常见错误现象:__('welcome') 返回空字符串、或直接输出 welcome 而不是翻译内容。这通常是因为语言文件没放对位置,或当前 locale 没匹配到任何语言包。
- 确保
resources/lang/zh_CN/messages.php(或en/messages.php)存在且返回关联数组,例如return ['welcome' => '欢迎']; -
config/app.php中设'locale' => 'zh_CN',注意下划线不是中划线;Laravel 不识别zh-CN - 语言目录名必须和
locale值完全一致,大小写敏感(zh_cn≠zh_CN)
Laravel 切换语言用 App::setLocale() 还是中间件
临时切换(比如单个请求内改语言)用 App::setLocale('ja') 最直接;但全局切换、用户偏好持久化、路由语言前缀等场景,必须靠中间件控制,否则容易出现视图渲染用旧 locale、API 响应用新 locale 的不一致。
性能影响:每次调用 App::setLocale() 都会重置翻译器缓存,高频切换(如循环内)会拖慢响应;中间件里设一次就够了。
- 不要在控制器方法开头反复调用
App::setLocale(),尤其别在循环或事件监听里 - 推荐在中间件中读取用户请求头
Accept-Language或 URL 参数(如?lang=fr),然后统一设置 - 若用了路由模型绑定或缓存响应,记得在中间件里设置 locale 后再进后续流程,否则缓存可能固化错误语言版本
带参数的翻译怎么写才不会出错(trans() vs __())
两者功能几乎一样,__() 是更简洁的辅助函数,底层都走 trans();区别只在语法糖层面,选哪个纯看团队习惯。真正容易踩坑的是参数传递方式。
错误示例:__('welcome_name', ['name' => $user->name]) 如果 messages.php 里写成 'welcome_name' => 'Hello :name',会正常;但如果写成 'Hello {name}' 或 'Hello $name',就完全不替换——Laravel 只认冒号占位符。
- 语言文件中必须用
:key格式,如'password_reset' => '你的重置链接将在 :count 分钟后失效' - 传参时键名要严格对应,
trans('auth.throttle', ['seconds' => 60])要求语言文件里也有':seconds' - 避免在翻译字符串里拼接 HTML,比如
'Click <a href="https://www.php.cn/link/263b1243ca2dbeb358777ceabc4a2e4c">here</a>'—— 会导致 XSS 风险且无法被翻译平台识别
为什么 Lang::has() 返回 false,但翻译实际能显示
这是因为 Lang::has() 默认只查当前 locale 对应的语言包,不查 fallback;而 __() 在找不到时会自动降级到 fallback_locale 再查一次。所以你看到翻译出来了,但 Lang::has('missing_key') 仍返回 false——它根本没去 fallback 包里找。
兼容性注意:Laravel 9+ 把 Lang 门面标记为废弃,推荐用 app('translator')->has(),行为一致,但更明确。
- 做存在性判断(比如动态生成语言选项)时,务必手动指定 fallback:
app('translator')->has('key', 'zh_CN') || app('translator')->has('key', 'en') - 别依赖
Lang::has()判断是否“有翻译”,它只反映“当前 locale 下是否有”,不是“系统是否支持该 key” - 如果启用了语言包缓存(
php artisan lang:publish或自定义缓存),记得清理缓存后再测试has()行为
语言包路径硬编码、locale 值大小写不一致、占位符格式错位——这三个点,比语法本身更容易让多语言功能“看起来开了,其实没起效”。










