本文目录导读:

在 PHP 框架(如 Laravel、ThinkPHP、Slim 等)中,全局中间件和路由中间件是两种核心的中间件注册与执行机制,它们的主要区别在于作用范围、执行时机以及应用场景。
以下是详细的对比分析:
核心区别一览表
| 特性 | 全局中间件 | 路由中间件 |
|---|---|---|
| 作用范围 | 整个应用的所有 HTTP 请求 | 仅指定的单个或多个路由 |
| 注册方式 | 在框架核心配置文件(如 Kernel.php, app.php)中全局注册 |
在路由定义文件(如 web.php, api.php)中绑定 |
| 执行顺序 | 通常最先执行(在路由匹配之前或之后),属于外层处理 | 在路由匹配成功后、控制器执行前执行 |
| 开销 | 每个请求都会触发,资源消耗较大 | 只有访问特定路由时才触发 |
| 典型用途 | 会话管理、CORS 跨域、请求日志、维护模式、CSRF 保护 | 权限校验、角色验证、特定 API 版本控制、路由参数预处理 |
详细概念解释
全局中间件
- 工作方式:在应用的整个生命周期中,对所有进入的 HTTP 请求都会执行。
- 执行时机:通常在框架的 HTTP 内核(Kernel)中定义,它们会在路由分发之前或者之后执行(取决于中间件的设计,Laravel 的
PreventRequestsDuringMaintenance是在路由之前)。 - 典型的全局中间件:
CheckForMaintenanceMode:检查网站是否在维护中。EncryptCookies:加密所有 Cookie。StartSession:启动会话(对所有页面都必需)。CorsMiddleware:跨域处理(通常所有 API 都需要)。
路由中间件
- 工作方式:只有当你请求的路由显式声明了该中间件时才会执行。
- 执行时机:在路由匹配成功后、正式进入控制器方法之前执行。
- 典型的应用场景:
Auth权限中间件:只对需要登录的后台路由生效。Role:admin角色中间件:只对管理员访问的路由生效。Throttle:60,1限流中间件:只对 API 接口(如/api/v1/order)生效。
代码示例(以 Laravel 框架为例)
全局中间件注册(app/Http/Kernel.php)
// app/Http/Kernel.php
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class, // 全局:所有请求都检查是否维护
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\Cors::class, // 全局:所有请求都处理跨域
];
路由中间件注册与使用
// app/Http/Kernel.php (定义别名)
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'admin' => \App\Http\Middleware\AdminAuth::class, // 自定义的
];
// routes/web.php (应用到具体路由)
Route::get('/admin/dashboard', function () {
// 业务逻辑
})->middleware(['auth', 'admin']); // 只对这两个路由使用
Route::get('/api/users', function () {
//
})->middleware('throttle:60,1'); // 只对API路由使用限流
选择建议
-
优先问自己:这个中间件需要所有请求都执行吗?
- 是 (\rightarrow) 使用全局中间件。
- 否 (\rightarrow) 使用路由中间件(或者分组中间件)。
-
性能考虑:
- 尽量避免在全局中间件中做数据库查询、外部 API 调用等耗时操作,因为这会拖慢每一个页面(包括静态资源请求或不需要该功能的页面)。
- 把权限检查、特定参数处理放在路由中间件中,只在必要时才执行。
-
业务场景匹配:
- 如果你是写一个 API 系统,几乎每个接口都要做 JWT 验证,可以考虑将这个验证放入全局中间件(但建议用分组),如果只有部分接口需要,必须用路由中间件。
- 日志记录通常做全局,因为你想记录所有请求。
- 用户认证通常做路由中间件,因为登录页面、首页通常不需要登录。
- 全局中间件 = 应用的“门卫”,每个入站请求都会经过。
- 路由中间件 = 路径的“检查站”,只有选择走这条路的人才会经过。
最佳实践:默认尽量使用路由中间件,只有当你明确需要“所有请求统一处理”(如 CORS、CSRF、会话启动)时,再升级为全局中间件,这样可以避免不必要的性能开销,保持架构清晰。