laravel多语言路由需用route::prefix('{locale}')->middleware('setlocale')并验证白名单,语言文件须放resources/lang/{locale}/{file}.php,__()/@lang需配合占位符参数,切换语言须通过session或cookie持久化并按优先级链推导locale。

怎么在 Laravel 路由里正确加载多语言前缀
路由必须显式支持语言参数,否则 app()->setLocale() 早于请求解析,本地化字符串不会按访问语言生效。
- 在
routes/web.php顶部加Route::prefix('{locale}')->middleware('setlocale'),别直接写死/en或/zh -
setlocale中间件要手动创建,里面调用app()->setLocale($request->locale),并验证$request->locale是否在config('app.locales')白名单里 - 别漏掉
fallback_locale配置 —— 当{locale}不匹配任何支持语言时,Laravel 默认用config('app.fallback_locale'),不是config('app.locale') - 生成 URL 时用
route('home', ['locale' => 'ja']),别拼字符串;否则带 locale 的命名路由会 404
Laravel 的 __() 函数为什么总返回英文
常见原因是语言文件没放对位置,或 key 写法和文件结构不匹配,__() 找不到对应翻译就回退到原始字符串(看起来像“没生效”)。
- 语言文件路径必须是
resources/lang/{locale}/{file}.php,比如日语的用户提示要放在resources/lang/ja/validation.php,不是resources/lang/ja/messages.php - 如果用
__('auth.failed'),就得确保resources/lang/en/auth.php里有'failed' => 'These credentials do not match our records.' - 执行
php artisan lang:publish并不能自动补全自定义语言包,它只复制框架内置的 en 文件;新增语言得手动建目录、复制+改内容 - 缓存开启时(
APP_DEBUG=false),修改语言文件必须运行php artisan view:clear && php artisan config:clear,否则旧翻译仍被读取
如何让 Blade 模板里的 @lang 支持变量插值
@lang 本身不解析占位符,它只是原样输出语言数组里的字符串;变量替换得靠 :attribute 这类命名占位符 + trans() 或 __() 的第二个参数。
- 语言文件中写
'custom_message' => 'The :attribute must be at least :min characters.' - 模板里用
{{ __('custom_message', ['attribute' => 'password', 'min' => 8]) }},不是@lang('custom_message', [...])(后者语法错误) - 验证规则中的 :attribute 是 Laravel 自动注入的,但自定义提示必须显式传参,
__('validation.custom.password.min', [...])也一样 - 别在语言文件里写 PHP 代码(如
= $var ?>),Laravel 不执行,只会当纯文本输出
切换语言时 session 或 cookie 怎么持久化
单纯改 app()->setLocale() 只影响当前请求;下次刷新又回到 config('app.locale'),必须把选择存下来并主动读取。
- 推荐用 session:用户点击语言切换链接时,发 POST 到
/locale/set,控制器里写session(['locale' => $request->locale]) - 然后在中间件里优先读
session('locale'),再 fallback 到 URL 参数、浏览器Accept-Language、最后才是配置默认值 - Cookie 方案更轻量,但注意
setcookie()在响应头发送,中间件里要用response()->withCookie(cookie('locale', $locale, 365 * 24)) - 别在
AppServiceProvider::boot()里硬编码app()->setLocale('fr')—— 这会让所有请求强制法语,覆盖用户选择
语言切换不是设个变量就完事,关键在「请求进来时,怎么从多个来源(URL / session / cookie / header)可靠地推导出本次该用哪个 locale」。这个决策链一旦写错,后面所有 __() 都白搭。










