laravel需手动设置语言环境,通过accept-language头、url前缀或查询参数/cookie获取并校验locale,在中间件中调用app::setlocale()确保翻译生效,语言文件目录名须与配置完全一致,且需配置fallback_locale兜底。

Laravel本身不自动“识别”语言,它需要你明确告诉它用哪种语言——关键在于谁来决定语言、何时设置、怎么验证。框架只负责按你指定的 locale 去加载对应翻译文件,不会猜测用户想看中文还是英文。
从请求中提取语言标识
常见来源有三个,选一个或组合使用:
-
Accept-Language 请求头:浏览器自动携带,如
zh-CN,zh;q=0.9,en;q=0.8。用$request->getPreferredLanguage(['en', 'zh', 'ja'])安全提取首选项,它会按权重和白名单返回合法值 -
URL 路径前缀:比如访问
/zh/about,通过$request->segment(1)拿到zh,再校验是否在配置的app.locales白名单里 -
查询参数或 Cookie:例如
?locale=ja或已存的user_localeCookie。注意必须校验该值是否合法,不能直接信任用户输入
在请求早期完成语言设置
必须在调用 __('xxx') 之前执行 App::setLocale($locale),否则一律走默认语言。推荐位置:
-
中间件:新建一个
SetLocale中间件,放在路由分组最前面(如web或api组),确保控制器和视图都能拿到正确 locale -
API 场景特别注意:不能依赖 session 或 cookie 自动带语言,每次请求都得显式设置;
FormRequest的验证错误消息也需在messages()方法里手动处理,避免被提前固化为默认语言
语言文件结构要严格匹配
哪怕一个字母不对,Laravel 就会静默回退到 fallback_locale,还不报错:
- 目录名必须与配置中的 locale key 完全一致,比如
config('app.locales')是['zh_CN', 'en_US'],就必须建resources/lang/zh_CN/和resources/lang/en_US/,不能写成zh-cn或chinese - 默认翻译文件名是
messages.php,__('welcome')查的就是它;其他文件如validation.php需显式写__('validation.required') - 键名只支持字母、数字、下划线和点号,
__('user login')会失败,应写作__('user_login')
兜底与容错不能少
用户看到空文案或原始键名,往往是因为没设好 fallback:
- 在
config/app.php中配好'fallback_locale' => 'en',确保任何缺失翻译都有备用 - 所有动态设置 locale 的地方(中间件、控制器)都要加白名单校验,非法值直接
abort(404)或忽略,别让App::setLocale('xxx')抛出InvalidArgumentException - 测试时手动改 URL 前缀或请求头,确认不同语言下文案确实切换,且缺失项能降级











