laravel中间件按洋葱模型执行,全局中间件在$middleware中顺序执行,路由组和单路由中间件优先级更高;依赖session/auth的中间件须置于$middlewaregroups['web']中startsession和authenticate之后,否则不可用。

中间件执行顺序怎么控制
Laravel 的中间件执行是洋葱模型,handle 方法里调用 $next($request) 才会进入下一层。不调用就中断请求,也不返回响应——这会导致白屏或超时。
- 全局中间件在
app/Http/Kernel.php的$middleware数组里,按顺序从上到下执行(进入),再倒序执行(退出) - 路由组中间件在
Route::middleware([...])中声明,优先级高于全局中间件,但只作用于该组路由 - 单个路由中间件如
Route::get('/admin')->middleware('auth'),会在路由匹配后、控制器执行前触发 - 如果在中间件里写了
return response()->json(...)但没加exit或抛异常,后续中间件和控制器仍可能执行——除非你明确 return 一个响应对象并终止流程
如何写一个带参数的中间件
中间件本身不直接支持参数传递,但 Laravel 允许在路由定义中以冒号分隔传参,比如 throttle:60,1,参数最终会作为字符串传给 handle 方法的第三个参数(即 $parameters 数组)。
- 定义中间件类时,
handle方法签名必须是public function handle($request, Closure $next, ...$parameters) -
...$parameters是可变参数,实际收到的是字符串切片后的数组,比如throttle:60,1→['60', '1'] - 别在中间件构造函数里依赖容器注入参数——参数只在运行时通过路由传入,构造阶段不可知
- 示例:校验用户角色的中间件
role:admin,editor,可在 handle 中用in_array($user->role, $parameters)判断
中间件里访问 session 或 auth 为什么有时为空
因为中间件执行顺序决定了依赖可用性。Laravel 默认中间件栈中,StartSession 和 Authenticate 并非最前——它们在 $middlewareGroups['web'] 里,而全局中间件($middleware)默认不包含它们。
- 如果你把自定义中间件注册在
$middleware(全局数组),它会在StartSession之前执行,此时$request->session()还未启动,auth()->user()必然为 null - 解决办法:把依赖 session/auth 的中间件放到
$middlewareGroups['web']里,确保它排在\App\Http\Middleware\StartSession::class和\Illuminate\Auth\Middleware\Authenticate::class之后 - 调试技巧:在中间件开头加
dd($request->hasSession(), auth()->check()),快速验证执行时机是否合理
为什么中间件里 redirect() 不生效或报错
常见错误是直接写 redirect('/login') 而没 return,或者在已发送响应后再次 redirect——Laravel 会抛出 HeadersAlreadySentException。
- 必须显式
return redirect('/login'),否则 PHP 继续执行后续逻辑,可能触发控制器或下一个中间件,造成意外交互 - 不能在中间件里先 echo / dd / response()->view() 再 redirect——输出一旦开始,HTTP 头无法再修改
- 如果用了
response()->redirectToRoute(...)->with(...)带闪存数据,要确认当前请求属于web中间件组(只有 web 组启用 session),否则with()无效 - API 场景慎用 redirect:API 请求通常期望 JSON 响应,重定向对前端 AJAX 来说难以处理,建议统一返回 401 + JSON 提示
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











