Laravel多语言依赖locale配置、lang目录结构和__()函数协同工作;需严格遵循resources/lang/{locale}/messages.php结构,动态切换须结合session或路由前缀并用中间件设置app()->setLocale(),验证翻译需手动添加validation.php文件。

Laravel 的多语言支持不是靠“设置开关”实现的,而是依赖 config/app.php 中的 locale 和 fallback_locale 配置,配合语言文件目录结构和 __() 辅助函数共同工作。直接改配置不写语言文件,或漏掉路由/中间件适配,90% 会失效。
怎么组织语言文件(lang/ 目录结构必须严格)
Laravel 要求语言文件必须放在 resources/lang 下,按语言代码分文件夹,每个文件夹内是 PHP 数组返回键值对:
resources/lang/
├── en/
│ └── messages.php
├── zh_CN/
│ └── messages.php
└── ja/
└── messages.php
注意:zh_CN 是合法语言代码,但 Laravel 默认不识别 zh-cn(带短横线),必须用下划线;文件名必须是 messages.php 或自定义名称(如 validation.php),但调用时要显式指定。
- 每个
messages.php返回关联数组,比如return ['welcome' => 'Welcome to our site']; - 嵌套键名可用点号,如
'auth.failed' => 'These credentials do not match our records.',调用时用__('auth.failed') - 不要在语言文件里写逻辑、调用函数或使用变量——它只是静态翻译映射
怎么动态切换语言(别只改配置,得持久化+路由适配)
修改 config/app.php 的 locale 只影响全局默认值,用户每次请求仍可能用旧语言。真要切换,得结合 session 或 URL 参数,并用中间件同步设置:
- 在中间件中调用
app()->setLocale($locale),例如从 session 读:app()->setLocale(session('locale', config('app.locale'))) - 如果用 URL 前缀(如
/zh_CN/login),需在routes/web.php中加语言参数,并用Route::group(['prefix' => '{locale}'], ...)包裹路由 - 切换后务必存回 session:
session(['locale' => 'ja']),否则刷新就回退 - 避免在控制器构造函数里设 locale——中间件执行更早,能确保视图、验证器等组件都用新语言
怎么让验证错误也本地化(validation.php 文件不能少)
表单验证失败提示默认走 resources/lang/{locale}/validation.php,这个文件 Laravel 不自动创建,必须手动补全:
- 复制
vendor/laravel/framework/src/Illuminate/Translation/Resources/lang/en/validation.php到你的resources/lang/en/validation.php,再翻译对应语言版本 - 键名必须完全一致,比如
'required' => ':attribute is required.',Laravel 验证器靠这个 key 匹配 - 如果用了自定义验证规则,要在对应语言的
validation.php里加新 key,否则 fallback 到英文 -
__('validation.required')这种写法无效——验证器内部自动拼接前缀,直接用__('required')即可(前提是当前 locale 下validation.php存在该 key)
常见失效原因和调试方法
页面没变中文?先看这几处:
- 浏览器请求头
Accept-Language不影响 Laravel 行为,别指望它自动切换 - 执行
php artisan lang:publish并不存在——Laravel 没这个命令,别被过时教程误导 - 缓存配置后改了
config/app.php必须运行php artisan config:clear,否则app()->getLocale()还是旧值 - Blade 中用
{{ __('welcome') }},但如果resources/lang/zh_CN/messages.php里没有'welcome'键,就会显示原文welcome,而不是报错——容易误以为“生效了” - API 接口返回的 JSON 字符串里含翻译内容?确保控制器里调用
__('xxx')前已 setLocale,且不依赖视图渲染流程
语言包本身没魔法,关键在三点:目录结构对、文件名对、运行时 locale 设置对。少一个,翻译就卡在半路。


















