如何在Laravel的Rule::requiredIf()验证中访问嵌套数组同层级元素
问题描述
我在自定义Request类中对数组进行验证,对应字段需要同时满足以下两个条件时判定为必填:
- 顶层字段
attribute3的值为true - 字段所属的同一个数组项内的另一个指定字段值为
true
我当前的实现代码如下:
public function rules() { return [ 'attribute1' => 'required', 'attribute2' => 'required', 'attribute3' => 'required', // 其他字段规则 'attribute10.*.column3' => Rule::requiredIf(fn() => $this->attribute3), // 数组字段规则 'attribute10.*.column4' => Rule::requiredIf(fn() => $this->attribute3), // 数组字段规则 'attribute10.*.column5' => Rule::requiredIf(fn() => $this->attribute3), // 数组字段规则 ]; }
我期望能在requiredIf的回调中获取到当前循环到的数组项,写法类似下面的示例:
'attribute10.*.column4' => Rule::requiredIf(fn($item /* 拿到当前循环的数组项 */) => $this->attribute3 && $item->column2 /* 直接用数组项的其他字段做判断 */),
解决方案
你可以通过提前遍历提交的数组项生成对应规则的方式实现需求,这种写法兼容性高、逻辑清晰,不需要依赖Laravel内部未公开的方法:
public function rules() { // 先定义固定的非数组字段规则 $rules = [ 'attribute1' => 'required', 'attribute2' => 'required', 'attribute3' => 'required', // 其他你需要的固定规则 ]; // 遍历提交的attribute10数组,逐个生成每个子项的验证规则 foreach ($this->input('attribute10', []) as $index => $item) { $requiredCondition = fn () => $this->attribute3 && (bool) ($item['column2'] ?? false); $rules["attribute10.{$index}.column3"] = Rule::requiredIf($requiredCondition); $rules["attribute10.{$index}.column4"] = Rule::requiredIf($requiredCondition); $rules["attribute10.{$index}.column5"] = Rule::requiredIf($requiredCondition); } return $rules; }
如果你使用Laravel 9及以上版本,还可以用验证器的当前属性方法拿到索引,写法更简洁:
'attribute10.*.column4' => Rule::requiredIf(function () { // 顶层条件不满足直接返回不需要必填 if (!$this->attribute3) return false; // 提取当前验证字段的数组索引 $index = explode('.', $this->validator->getCurrentAttribute())[1]; // 判断同数组项的column2是否为true return (bool) $this->input("attribute10.{$index}.column2", false); }),
第二种方法依赖Laravel默认的Request类验证器实例注入特性,常规项目都可以直接使用。
内容的提问来源于stack exchange,提问作者Petyor
相关产品推荐
相关产品推荐

