Laravel怎么开启多语言支持 _ Laravel 语言包切换方法【指南】

3次阅读

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

Laravel怎么开启多语言支持 _ Laravel 语言包切换方法【指南】

怎么在 Laravel 里启用多语言(i18n)基础支持

Laravel 默认已内置多语言支持,不需要额外装包,但必须手动启用——关键动作是配置 config/app.php 中的 localefallback_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_cnzh_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 值大小写不一致、占位符格式错位——这三个点,比语法本身更容易让多语言功能“看起来开了,其实没起效”。

text=ZqhQzanResources