You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel 11全局中间件获取Session返回null问题求助

问题:Laravel 11全局中间件无法读取Session实现本地化

我的实现代码

1. SetLocale中间件

public function handle(Request $request, Closure $next): Response
{
    App::setLocale(session()->get('locale'));
    return $next($request);
}

2. 全局中间件配置(bootstrap/app.php)

return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__ . '/../routes/web.php',
        commands: __DIR__ . '/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(SetLocale::class);
    })
    ->withExceptions(function (Exceptions $exceptions) {
        //
    })->create();

3. LocalizationController设置Session

public function setLocalization(string $locale): RedirectResponse
{
    session()->put('locale', $locale);
    App::setLocale($locale);
    return back();
}

4. 路由配置(web.php)

Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');

已尝试但无效的操作

  • 全程使用Session门面;
  • 在setLocalization方法中返回back()->with('locale', $locale);
  • 多次调整代码,仍无法在中间件中获取到locale的Session数据。

唯一可行的方式

将中间件绑定到路由组时能正常工作:

Route::prefix('localization')->middleware([SetLocale::class])->group(function() {
   Route::get('/locale/{locale}', [LocalizationController::class, 'setLocalization'])->name('locale.switch');
});

疑问

是我对全局中间件的使用方式有误,还是Laravel 11修改了全局中间件的Session处理逻辑?注:Laravel 11的中间件配置已迁移至bootstrap/app.php文件。


问题原因及解决方案

核心原因

Laravel 11中,全局中间件的执行顺序早于StartSession中间件。你通过append添加的全局中间件会在StartSession之前运行——此时Session还未初始化,自然读不到session里的locale值。

而路由组绑定中间件时,中间件是在web路由组的默认中间件(包括StartSession)之后执行的,所以能正常读取Session。

正确配置方式

把SetLocale中间件添加到web中间件组,确保它在Session初始化后执行。修改bootstrap/app.php中的中间件配置:

->withMiddleware(function (Middleware $middleware) {
    // 将中间件添加到web组,而非全局append
    $middleware->web([
        \App\Http\Middleware\SetLocale::class,
    ]);
})

额外优化建议

  1. 给locale设置默认值,避免Session无值时报错:
// SetLocale中间件中
App::setLocale(session()->get('locale', config('app.locale')));
  1. 验证传入的locale合法性,防止非法值:
// LocalizationController中
public function setLocalization(string $locale): RedirectResponse
{
    // 替换成你实际支持的语言列表
    $supportedLocales = ['zh-CN', 'en'];
    if (in_array($locale, $supportedLocales)) {
        session()->put('locale', $locale);
        App::setLocale($locale);
    }
    return back();
}

内容的提问来源于stack exchange,提问作者Sreekesh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 09:35:13