laravel中创建参数校验中间件需用php artisan make:middleware validaterequest生成,编辑handle方法实现规则验证与422响应,注册到$routemiddleware或$middlewaregroups['api'],支持通过middleware('validate:register')传参动态切换规则,注意挂载位置、路由绑定及return $next($request)不可遗漏。

在 Laravel 中实现请求过滤和全局参数校验,核心不是堆功能,而是理清中间件的“拦截-放行”本质,并把校验逻辑放在合适的位置。它不依赖复杂配置,关键在注册位置、执行顺序和 handle 方法的返回控制。
怎么创建并注册一个参数校验中间件
用 Artisan 命令快速生成:
php artisan make:middleware ValidateRequest
生成文件位于 app/Http/Middleware/ValidateRequest.php。打开后,在 handle 方法中写校验逻辑,例如检查必填字段:
- 从请求中提取参数:
$data = $request->only(['email', 'name', 'age']); - 定义规则数组:
$rules = ['email' => 'required|email', 'name' => 'required|string|max:50']; - 调用 Laravel 验证器:
$validator = Validator::make($data, $rules); - 验证失败时直接返回响应:
if ($validator->fails()) { return response()->json(['errors' => $validator->errors()], 422); } - 通过则继续:
return $next($request);
注册方式分两类:
- 若需对所有 API 接口统一校验,加到 app/Http/Kernel.php 的
$routeMiddleware数组中,如:'validate' => \App\Http\Middleware\ValidateRequest::class - 若只用于特定路由组(如全部 API),可绑定到
$middlewareGroups['api']中,但要注意它会覆盖默认 api 组行为,慎用
如何让中间件支持动态参数(比如指定校验场景)
Laravel 不通过构造函数传参,而是靠字符串解析。例如在路由中这样写:
Route::post('/user', [UserController::class, 'store'])->middleware('validate:register');
对应中间件的 handle 方法签名要改为:
public function handle(Request $request, Closure $next, string $scene)
然后根据 $scene 加载不同规则:
if ($scene === 'register') { $rules = [...]; }elseif ($scene === 'update') { $rules = [...]; }
这种写法避免重复建多个中间件类,也方便后期扩展。
为什么中间件写了却不生效?三个高频原因
不是代码没写对,而是挂载错了地方:
-
注册位置错:把本该放在
$routeMiddleware的中间件误加进$middleware(全局数组),结果连 favicon.ico、health 检查都卡住 -
路由没绑定:注册了
'validate' => ...,但在路由里忘记写->middleware('validate') -
handle 方法漏 return:写了
$next($request)却没加return,或条件分支里只写了 if 没写 else,导致非预期请求直接穿透到控制器
调试技巧:在 handle 开头加一行 Log::debug('validate middleware triggered', ['url' => $request->fullUrl()]);,看日志是否出现。
全局参数校验的最佳实践组合
真正健壮的校验不是靠单个中间件,而是分层协作:
-
最外层:用
TrimStrings和ConvertEmptyStringsToNull(Laravel 默认全局中间件),做基础清洗 -
中间层:自定义
ValidateRequest,做业务字段级校验,返回标准 422 错误 - 内层:在控制器方法里再做轻量逻辑判断(如密码确认一致性),避免中间件过度耦合
注意顺序:校验中间件必须放在 StartSession 和 VerifyCsrfToken 之后(如果是 web 组),否则拿不到 session 数据;但不能放在 EncryptCookies 之前,否则无法读取加密 cookie 中的 token。











