中间件需显式注册到路由,支持单个、多个、路由组及全局方式;参数仅支持字符串格式,通过handle()第三参数获取;执行顺序错误或遗漏return将导致请求中断。

中间件怎么注册到路由上
直接在路由定义里用 middleware() 方法绑定,这是最常用也最直观的方式。Laravel 不会自动把中间件和路由扯上关系,必须显式声明。
- 全局中间件(如
VerifyCsrfToken)在app/Http/Kernel.php的$middleware数组里,对所有请求生效,不推荐用来做业务逻辑拦截 - 路由组中间件写在
Route::group()的middleware键里,适合统一加权限或日志 - 单个路由中间件直接链式调用:
Route::get('/profile', [ProfileController::class, 'show'])->middleware('auth') - 多个中间件可以传数组:
->middleware(['auth', 'verified']),顺序重要——靠前的先执行
中间件类没被找到?检查命名空间和自动加载
报错 Class "App\Http\Middleware\CheckRole" not found 是典型路径问题,不是语法错,而是 PHP 自动加载失败。
- 确认中间件类文件在
app/Http/Middleware/下,且类名与文件名严格一致(如CheckRole.php里是class CheckRole) - 检查
use语句是否漏了命名空间,比如在控制器里调用中间件时写App\Http\Middleware\CheckRole::class,而不是裸名 - 如果自定义了中间件目录(比如放在
app/Middleware/),要手动在composer.json的"autoload": {"psr-4": {...}}里加映射,并运行composer dump-autoload - Laravel 10+ 默认启用「FQCN(全限定类名)」注册方式,不支持字符串别名(如
'check.role'),除非你在app/Http/Kernel.php的$routeMiddleware里显式绑定了别名
中间件参数怎么传:只支持字符串,不能传对象或数组
想让中间件接收动态值(比如权限码、模块名),只能通过字符串形式传参,Laravel 路由解析器只认这个格式。
- 写法是
->middleware('role:admin,editor'),中间件构造函数收不到这个,得在handle()方法里从$request或闭包参数中取 - 中间件类的
handle()第三个参数$parameters就是拆好的字符串数组:['admin', 'editor'] - 别试图传 JSON 或序列化数据:
->middleware('log:{"level":"debug"}')会直接报错或被当作文本解析,不可靠 - 如果逻辑复杂(比如要查数据库判断权限),建议把参数设计成 ID 或标识符,具体逻辑放
handle()里处理,别塞进参数字符串里“图省事”
中间件执行顺序错了,页面白屏或跳转异常
中间件像洋葱一层层套着请求,顺序错一环,$next($request) 没被调用,请求就卡死,常见于自定义中间件里忘了 return 或 throw 了但没 catch。
- 检查每个中间件的
handle()是否都有return $next($request)—— 缺少 return 是最隐蔽的白屏原因 - 如果中间件里做了重定向(
redirect())或终止响应(abort()),确保前面没其他中间件已发送响应,否则会触发Headers already sent - 调试顺序:在每个中间件开头加
Log::info('in middleware X'),看日志输出顺序是否符合预期 - 注意内建中间件(如
StartSession)依赖前置条件,把它放到EncryptCookies后面是安全的,但反过来可能读不到 session 数据
中间件不是黑盒插件,它和路由生命周期深度耦合;最常出问题的地方不在注册语法,而在 handle 里忘了 return,或者参数解析时假设了不存在的结构。



















