Laravel FormRequest中如何在某一校验通过后追加额外校验规则
实现方案(基于Laravel验证体系)
你完全可以通过Laravel提供的验证后钩子或者分步校验的方式实现这个需求,以下是两种可行的实现方式:
方式1:使用表单请求的after校验钩子
如果是用自定义表单请求类,直接在rules方法定义基础规则,再在withValidator方法追加后置校验逻辑即可:
// 首先定义基础校验规则 public function rules() { return [ 'name' => ['required', 'string', 'min:3', 'max:30'], 'password' => ['required', 'min:6'], 'photo' => ['imageable'], 'business_uuid' => ['required', 'uuid', 'exists:businesses,uuid'], ]; } public function withValidator($validator) { // 只有基础规则全部校验通过后,才会执行这里的逻辑 $validator->after(function ($validator) { if ($validator->failed()) { return; } // 从已经校验通过的business_uuid拿到对应业务记录 $business = \App\Models\Business::where('uuid', $this->input('business_uuid'))->first(); $countryCode = $business->country_code; // 手动追加phone字段的校验 $phoneValidator = \Validator::make($this->input(), [ 'phone' => ['nullable', 'phone:'.$countryCode], ]); if ($phoneValidator->fails()) { // 把phone的校验错误合并到主校验器的错误信息里 $validator->errors()->merge($phoneValidator->errors()); } }); }
方式2:控制器内分步校验
如果是在控制器里直接写校验逻辑,也可以拆成两步来做:
// 第一步先校验基础规则,不包含phone $validated = $request->validate([ 'name' => ['required', 'string', 'min:3', 'max:30'], 'password' => ['required', 'min:6'], 'photo' => ['imageable'], 'business_uuid' => ['required', 'uuid', 'exists:businesses,uuid'], ]); // 拿到对应业务的国家代码 $business = \App\Models\Business::where('uuid', $validated['business_uuid'])->first(); $countryCode = $business->country_code; // 第二步校验phone字段 $validated = array_merge($validated, $request->validate([ 'phone' => ['nullable', 'phone:'.$countryCode], ]));
注意:第二种方式如果第一步校验失败会直接返回错误,不会走到后面的phone校验逻辑,完全符合你“business_uuid校验通过后才处理phone规则”的要求。
内容的提问来源于stack exchange,提问作者Omar Abdelaziz
相关产品推荐
相关产品推荐

