Laravel中trait内验证规则被控制器调用时不生效怎么办
问题根因
两个核心问题导致校验不生效:
- 没有返回校验失败的响应:trait里的
pagination()方法虽然在校验失败时生成了400状态码的JSON响应,但控制器调用该方法时没有接收、返回这个响应对象,生成的错误响应被直接丢弃,代码会继续执行后续的业务逻辑。 - 校验规则缺省场景不生效:当前写的
integer|gt:4类规则遵循Laravel默认校验逻辑——如果请求中没有携带对应参数,会直接跳过该字段的所有校验,未传page/per_page时不会触发校验拦截。
修复方案
方案1:修改trait校验失败抛异常(推荐)
这种写法不需要修改控制器调用逻辑,Laravel框架会自动捕获验证异常,返回对应格式的错误响应,从根源避免漏写返回的问题。同时给规则加上required,强制参数必传。
trait ValidatePagination { protected function pagination(Request $request) { $rules = [ 'page' => 'required|integer|gt:4', 'per_page' => 'required|integer|gt:0|lte:100', ]; // 直接调用请求的validate方法,校验失败自动抛出ValidationException $request->validate($rules); // 如果保留Validator门面的写法,校验失败手动抛异常即可 // $validator = \Validator::make($request->all(), $rules); // if ($validator->fails()) { // throw new \Illuminate\Validation\ValidationException($validator); // } } }
方案2:保留trait返回响应的写法,调整控制器调用逻辑
如果不想用抛异常的方式,就在控制器调用校验方法后接收返回值,校验失败时直接把错误响应返回给客户端。
控制器方法修改后代码:
public function get(Request $request): JsonResponse { $companyId = $request['user']->cid; $perPage = $request->query('per_page', 15); // 接收校验方法返回值 $validationResponse = $this->pagination($request); // 校验失败时直接返回错误响应,终止后续逻辑 if ($validationResponse) { return $validationResponse; } $staffTable = TableBuilder::get($companyId, STAFF); $staff = $staffTable->get(['pid', 'name', 'mobile', 'pay_rate', 'is_working', 'pay_start_date', 'pay_end_date']); $staff = $staffTable->orderBy('updated_at', 'desc')->simplePaginate($perPage); return $this->success('Fetched staff members', $staff); }
注意:这种写法每次调用
pagination()都需要加返回判断,漏写就会复现当前的校验失效问题。
内容的提问来源于stack exchange,提问作者badrinath
相关产品推荐
相关产品推荐

