Laravel Validation:如何组合required与exists实现条件验证?
解决Laravel动态验证规则被覆盖的问题
嘿,我太懂你碰到的这个坑了——PHP数组里重复的键会直接被后面的覆盖,所以你两次定义lines.*.sku的规则,最后只有第二行的生效,这很正常。不过咱们有两种简单的方法来实现你要的动态验证逻辑:
方法1:使用Laravel内置的条件验证规则组合
Laravel的验证规则支持用数组形式组合多个条件,刚好能满足你的需求:
$validation = $this->validate($request, [ 'inventory_purchase_bill' => 'required|boolean', 'lines.*.sku' => [ 'nullable', 'exists:items,sku', 'required_if:inventory_purchase_bill,true', ], ]);
规则逻辑拆解:
- 当
inventory_purchase_bill为true时,required_if规则会强制sku必须有值,同时exists校验确保这个sku在items表中存在; - 当
inventory_purchase_bill为false时,nullable允许sku为null或空值,但如果传入了具体值,exists规则依然会生效,完美匹配你“仅当有值时校验exists”的要求。
方法2:动态构建验证规则数组
如果你觉得数组组合的方式不够直观,也可以根据请求参数的值动态生成规则:
// 基础规则 $rules = [ 'inventory_purchase_bill' => 'required|boolean', ]; // 根据inventory_purchase_bill的值追加动态规则 if ($request->inventory_purchase_bill) { $rules['lines.*.sku'] = 'required|exists:items,sku'; } else { $rules['lines.*.sku'] = 'nullable|exists:items,sku'; } // 执行验证 $validation = $this->validate($request, $rules);
这种方式逻辑清晰,一眼就能看出来不同场景下的规则差异,后期维护也更方便。
为什么你原来的写法不行?
在PHP中,关联数组的键是唯一的,当你连续两次定义'lines.*.sku'这个键时,后一次赋值会直接覆盖前一次的规则,所以只有最后一行的规则会被执行。
内容的提问来源于stack exchange,提问作者Lucid Polygon
相关产品推荐
相关产品推荐

