Laravel 多语言支持需正确设置 resources/lang 下语言子目录(如 zh_CN)、使用 __() 函数、动态调用 App::setLocale() 而非硬编码 config/app.php,并确保翻译键名一致、避免中间件覆盖及 Blade 中统一用 {{ __('key') }}。

怎么在 Laravel 里启用多语言支持
Laravel 自带的 lang 目录和 __() 函数就是为多语言准备的,不用装额外包。关键不是“能不能”,而是“目录结构对不对”和“locale 设置有没有被覆盖”。
-
resources/lang下必须按语言建子目录,比如resources/lang/en、resources/lang/zh_CN(注意不是zh或cn) - 每个子目录里放 PHP 文件,如
messages.php,返回关联数组:return ['welcome' => 'Welcome']; - 别在
config/app.php里硬写'locale' => 'zh_CN'—— 这会让全站固定成中文,切不了语言 - 实际切换靠动态设置:
App::setLocale($locale),且必须在路由或中间件里尽早调用,否则视图渲染时已用默认 locale 加载了翻译
如何安全地切换中英文(不刷新页面)
前端点一下按钮就变语言,后端得接住请求、改 session、再返回新内容。核心是别动 config('app.locale'),它只是初始值;真正起作用的是运行时的 App::currentLocale()。
- 写个 POST 路由,比如
/set-locale,接收locale=zh_CN或en - 在控制器里先校验输入:
in_array($request->locale, ['en', 'zh_CN']),防止任意 locale 导致文件未找到 - 存到 session:
session(['locale' => $request->locale]),然后立刻调用App::setLocale($request->locale) - 别忘了响应 JSON,前端才能知道成功与否;如果返回视图,得确保该视图里所有
__('xxx')都在 setLocale 之后执行
为什么 __('welcome') 总显示英文,明明已调用 App::setLocale('zh_CN')
最常见原因是翻译文件路径或键名不匹配,Laravel 不报错,静默回退到原始字符串。
- 检查
resources/lang/zh_CN/messages.php是否存在,且包含'welcome' => '欢迎'—— 键名必须完全一致,包括大小写和下划线 - 确认你没在某个服务提供者或中间件里又调了一次
App::setLocale('en'),后面调用会覆盖前面的 - Blade 模板里如果用了
@lang('welcome'),它不走__()流程,不会响应 locale 切换,统一用{{ __('welcome') }} - Artisan 命令或队列任务里默认没有 session,
App::currentLocale()是config('app.locale'),切语言无效
中英文切换时日期、数字格式怎么同步变
Laravel 的本地化不只是翻译字符串,Carbon 和 NumberFormatter 也依赖当前 locale。但它们不自动读 App::currentLocale(),得手动桥接。
- Carbon 日期本地化:调用
Carbon::setLocale($locale),比如zh_CN对应中文星期和月份;注意这是全局静态设置,多用户并发时有风险 - 更稳妥的做法是每次格式化前指定 locale:
Carbon::now()->locale('zh_CN')->translatedFormat('j F Y') - 数字千分位和小数点:用
NumberFormatter,传入new \NumberFormatter($locale, \NumberFormatter::DECIMAL),别依赖config('app.locale') - 数据库字段如果是时间类型(datetime),它本身没 locale,格式化必须在 PHP 层做,不能指望 MySQL
DATE_FORMAT()自动适配用户语言
真正麻烦的不是配置,是那些隐式依赖 locale 的地方:邮件模板里的日期、API 返回的提示文案、甚至第三方 SDK 抛出的错误信息。这些地方一旦漏掉 setLocale,用户看到的就是中英混杂的界面。










