Laravel web路由中setLocale设置多语言不生效问题排查
Laravel
setLocale 语言切换不生效问题修复 核心原因
你当前的代码仅在访问语言切换路由的单次请求内调用了setLocale(),虽然将语言标识存入了Session,但没有在每次请求初始化时从Session读取语言值并全局生效。Laravel默认每次请求启动时都会将应用语言重置为config/app.php中配置的默认值,因此重定向回原页面后,之前临时设置的语言就会失效,页面始终显示默认语言。
现有代码的具体问题
- 路由闭包内的
App()->setLocale($lang)仅在/language/{lang}这一个请求的生命周期内生效,执行redirect()->back()产生的新请求不会自动沿用该设置。 - 存入Session的
locale值没有配套的逻辑在请求启动时读取,存储操作没有实际业务价值。 - 缺少传入语言参数的合法性校验,如果用户传入不在支持列表内的语言值,可能引发异常。
修复方案
- 创建全局语言中间件
执行Artisan命令生成中间件文件:
php artisan make:middleware SetLocale
- 编写中间件逻辑
打开app/Http/Middleware/SetLocale.php,替换为以下代码,实现请求启动时自动读取Session设置语言:
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Http\Request; use Illuminate\Support\Facades\App; use Illuminate\Support\Facades\Session; class SetLocale { public function handle(Request $request, Closure $next) { $locale = Session::get('locale', config('app.locale')); // 校验语言合法性,避免非法参数导致异常 if (in_array($locale, config('app.languages'))) { App::setLocale($locale); } return $next($request); } }
- 注册中间件到Web路由组
打开app/Http/Kernel.php,将刚写好的中间件加入web中间件组,确保所有Web路由请求都经过语言设置逻辑:
protected $middlewareGroups = [ 'web' => [ // 保留原有其他web中间件 \App\Http\Middleware\SetLocale::class, ], // 其他中间件组保持不变 ];
- 优化原有语言切换路由
给路由增加参数校验,移除无实际作用的临时setLocale调用:
Route::get('language/{lang}', function ($lang) { if (!in_array($lang, config('app.languages'))) { abort(400); } session()->put('locale', $lang); return redirect()->back(); })->name('langroute');
补充说明:前端视图部分的代码没有逻辑问题,完成以上修改后,语言切换即可正常生效。
内容的提问来源于stack exchange,提问作者jhon jhon
相关产品推荐
相关产品推荐

