Laravel中间件是处理HTTP请求的重要组件,能够在请求到达目标处理逻辑之前或之后执行指定的操作,常用于身份验证、请求日志、跨域处理等场景。路由和控制器都可以配置中间件,两者配合可以实现灵活的请求管控逻辑。

中间件的基础创建
首先可以通过Artisan命令创建自定义中间件,执行以下命令会生成中间件文件:
<?php
namespace AppHttpMiddleware;
use Closure;
class CheckUserStatus
{
/**
* 处理传入的请求
*
* @param IlluminateHttpRequest $request
* @param Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
// 检查用户状态逻辑
if (!$request->user() || $request->user()->status != 1) {
return redirect('/login');
}
return $next($request);
}
}
路由层面配置中间件
在路由定义时可以直接为单个路由或路由组绑定中间件,这种方式适合针对特定路由规则统一添加处理逻辑。
单个路由配置
使用middleware方法为单个路由绑定中间件:
<?php
use AppHttpMiddlewareCheckUserStatus;
use IlluminateSupportFacadesRoute;
Route::get('/user/profile', function () {
return view('profile');
})->middleware(CheckUserStatus::class);
路由组配置
如果多个路由需要使用同一个中间件,可以将它们放到同一个路由组中:
<?php
use AppHttpMiddlewareCheckUserStatus;
use IlluminateSupportFacadesRoute;
Route::middleware([CheckUserStatus::class])->group(function () {
Route::get('/user/order', function () {
return view('order');
});
Route::get('/user/address', function () {
return view('address');
});
});
控制器层面配置中间件
在控制器的构造函数中配置中间件,可以让中间件仅对该控制器的所有方法或指定方法生效,适合控制器级别的请求过滤。
控制器全局配置
在控制器的__construct方法中调用middleware方法,会为控制器的所有方法添加中间件:
<?php
namespace AppHttpControllers;
use AppHttpMiddlewareCheckUserStatus;
use IlluminateHttpRequest;
class UserController extends Controller
{
public function __construct()
{
$this->middleware(CheckUserStatus::class);
}
public function profile()
{
return view('user.profile');
}
public function order()
{
return view('user.order');
}
}
指定方法配置
可以通过only或except方法指定中间件生效的方法范围:
<?php
namespace AppHttpControllers;
use AppHttpMiddlewareCheckUserStatus;
use IlluminateHttpRequest;
class UserController extends Controller
{
public function __construct()
{
// 仅对profile方法生效
$this->middleware(CheckUserStatus::class)->only('profile');
// 对除order外的所有方法生效
// $this->middleware(CheckUserStatus::class)->except('order');
}
public function profile()
{
return view('user.profile');
}
public function order()
{
return view('user.order');
}
public function address()
{
return view('user.address');
}
}
路由与控制器的协同使用场景
路由和控制器配置中间件可以结合使用,实现更细粒度的请求管控:
- 通用中间件(如跨域处理、请求日志)可以在路由组层面配置,覆盖所有相关路由
- 控制器专属的业务中间件(如用户状态校验)可以在控制器层面配置,避免重复绑定
- 如果某个路由需要额外的中间件,可以在路由层面单独追加,不影响控制器的其他配置
以下是协同使用的示例,路由组配置了跨域中间件,控制器配置了用户状态校验中间件,同时单个路由追加了请求频率限制中间件:
<?php
use AppHttpControllersUserController;
use AppHttpMiddlewareCorsMiddleware;
use IlluminateSupportFacadesRoute;
// 路由组配置通用跨域中间件
Route::middleware([CorsMiddleware::class])->group(function () {
// 控制器已配置用户状态中间件,该路由自动继承
Route::get('/user/profile', [UserController::class, 'profile']);
// 单个路由追加频率限制中间件
Route::get('/user/order', [UserController::class, 'order'])->middleware('throttle:60,1');
});
中间件配置注意事项
配置中间件时需要注意以下几点:
- 自定义中间件需要先注册到
app/Http/Kernel.php的对应数组中,否则可能无法正常调用 - 中间件的执行顺序按照绑定的先后顺序执行,路由层面的中间件会先于控制器层面的中间件执行
- 如果路由和控制器配置了同一个中间件,该中间件只会执行一次,不会重复处理
中间件的核心作用是解耦请求处理逻辑,合理搭配路由和控制器的中间件配置,可以让代码结构更清晰,维护成本更低。