Laravel中如何定义中间件_Laravel Middleware中间件注册与使用教程【详解】

9次阅读

中间件类无需继承任何类,只需实现handle方法并调用$next($request);注册分全局、分组、单路由三层;参数通过逗号分隔传入handle第三及后续参数。

Laravel中如何定义中间件_Laravel Middleware中间件注册与使用教程【详解】

中间件类必须继承 IlluminateBusMiddlewaredispatchable 吗?

完全不需要。这是常见误解——Dispatchable 是用于命令总线(Bus)的 trait,和中间件无关。laravel 中间件本质就是一个带 handle() 方法的普通 php 类,只要它接受 $request$next 两个参数,并最终调用 $next($request) 即可。

正确基类是空的,无需继承任何类(当然你也可以选择继承 IlluminatehttpMiddlewareTrustProxies 这类已有的中间件基类,但非常少见)。官方推荐写法就是:

class CheckAge {     public function handle($request, Closure $next)     {         if ($request->age < 20) {             return redirect('home');         }          return $next($request);     } }

如何注册中间件:全局、分组、单路由三者怎么选?

注册位置决定作用范围,选错会导致中间件不生效或过度执行。

  • 全局中间件:在 app/Http/Kernel.php$middleware 数组里,对所有 HTTP 请求生效(包括 API 和 Web),适合日志、CORS、请求解析等基础设施层逻辑
  • 分组中间件:在 $middlewareGroups 里,比如 webapi。路由用 Route::middleware(['web']) 或直接用 Route::group(['middleware' => ['web']], ...) 调用。注意:Laravel 默认给 routes/web.php 自动套了 web 组,所以你在里面写的路由默认已有 sessioncsrf 等中间件
  • 单路由中间件:最细粒度控制,直接链式调用 ->middleware(CheckAge::class)。适合权限校验、数据预加载等业务强相关逻辑

别把需要鉴权的 CheckAge 放进 $middleware 全局数组——它会在每次请求(包括静态资源、健康检查接口)里执行,浪费性能且可能报错。

handle() 方法里忘记调用 $next($request) 会怎样?

请求会在这里「卡住」,既不向下传递,也不返回响应,最终超时或抛出 IlluminateRoutingExceptionsInvalidSignatureException(如果用了签名中间件)之类难以定位的异常。更常见的是浏览器一直转圈、API 返回空响应、nginx504 gateway Timeout

务必确保每个分支都返回值:

public function handle($request, Closure $next) {     if ($request->user() && $request->user()->banned) {         return response('Banned!', 403); // ✅ 返回响应     }      if ($request->expectsjson()) {         return $next($request); // ✅ 继续执行     }      return redirect('/login'); // ✅ 显式返回 }

不要写 if (...) { return ...; } 然后后面没 return —— PHP 不会自动补全,这属于硬性逻辑错误。

中间件参数怎么传?check:role,admin 是怎么解析的?

路由定义中写的 ->middleware('check:role,admin'),Laravel 会把 role,admin 当作字符串传给中间件的 handle() 第三个参数(需手动声明):

public function handle($request, Closure $next, $type, $value) {     // $type = 'role', $value = 'admin'     if ($type === 'role') {         if (!$request->user() || !$request->user()->hasRole($value)) {             abort(403);         }     }      return $next($request); }

注意:$type$value 的顺序必须和 : 后逗号分隔的顺序一致,且参数个数要匹配。多于或少于都会报 Too few arguments to function 错误。没有参数就别写冒号,写成 ->middleware(CheckAge::class) 即可。

参数只支持字符串,不能传数组或对象;复杂逻辑建议改用请求属性或 session 存储,而非塞进中间件参数里。

text=ZqhQzanResources