Laravel FormRequest中如何基于嵌套数组值配置Rule::requiredIf验证
假设我有以下FormRequest验证规则片段,请问应如何声明验证规则,才能使Rule::requiredIf生效?
public function rules() { return [ .... 'sections.*.content.*.type' => [ 'required', ], 'sections.*.content.*.categories' => [ Rule::requiredIf('sections.*.content.*.type' == 'category'), 'array' ], 'sections.*.content.*.banners' => [ Rule::requiredIf('sections.*.content.*.type' == 'banner'), 'array' ] ]; }
正确实现动态必填规则的方法
你的写法存在两个核心问题:
'sections.*.content.*.type' == 'category'是静态字符串比较,会直接返回false,无法动态读取请求中对应字段的实际值- 针对嵌套通配符字段(
sections.*.content.*),需要用Rule::forEach()遍历每个元素,才能关联对应位置的type值
正确的代码实现如下:
use Illuminate\Validation\Rule; public function rules() { return [ // 其他规则... 'sections.*.content.*.type' => ['required'], 'sections.*.content.*.categories' => [ Rule::forEach(function ($value, $attribute) { // 从当前字段路径中解析出对应type字段的路径 $typeAttribute = str_replace('.categories', '.type', $attribute); // 判断对应位置的type值是否为'category',以此决定是否必填 return Rule::requiredIf($this->input($typeAttribute) === 'category'); }), 'array' ], 'sections.*.content.*.banners' => [ Rule::forEach(function ($value, $attribute) { $typeAttribute = str_replace('.banners', '.type', $attribute); return Rule::requiredIf($this->input($typeAttribute) === 'banner'); }), 'array' ] ]; }
关键说明:
Rule::forEach()会遍历所有匹配到的嵌套字段(比如sections[0].content[0].categories),回调函数的$attribute参数就是当前字段的完整路径- 通过
str_replace替换路径后缀,就能精准定位到同层级的type字段 - 用
$this->input($typeAttribute)获取该字段的实际值,动态判断是否需要启用必填规则
也可以通过拆分字段索引的方式构建type路径,效果一致:
// 以categories字段为例,拆分路径获取索引 [$sectionKey, , $contentKey] = explode('.', $attribute); $typeAttribute = "sections.$sectionKey.content.$contentKey.type";
内容的提问来源于stack exchange,提问作者Luciano
相关产品推荐
相关产品推荐

