Laravel嵌套验证请求:获取字段实现自定义验证与组合去重
Laravel嵌套数组验证解决方案
一、自定义验证器获取对应项的product_id与product_collection_id
你当前代码中直接通过$this->details.*->product_id传递参数的方式无效,因为在表单请求的rules方法中无法直接动态获取数组索引对应的字段值。正确做法是让自定义验证器通过属性路径自行提取对应字段:
1. 编写ProductAndCollectionValidator规则
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class ProductAndCollectionValidator implements Rule { public function passes($attribute, $value) { // 从属性名中解析出数组索引,例如"details.0.product_collection_id" -> 索引0 $segments = explode('.', $attribute); $index = $segments[1]; // 获取当前项对应的product_id $productId = request()->input("details.$index.product_id"); // 当前项的product_collection_id(可能为null) $collectionId = $value; // 此处编写你的核心验证逻辑 // 示例:若collection_id不为null,校验产品是否属于该集合 if (!is_null($collectionId)) { // 替换为你的实际业务逻辑,比如: // $product = \App\Models\Product::find($productId); // return $product && $product->product_collection_id == $collectionId; } // 若collection_id为null,默认验证通过(可根据需求调整) return true; } public function message() { return '产品与集合的组合无效'; } }
2. 更新验证规则配置
在表单请求的rules方法中,只需实例化验证器,无需传递参数:
return [ // ...其他规则 'amount' => ['nullable', 'numeric'], 'currency_id' => ['nullable', 'integer', Rule::in($allowedCurrencyIds)], 'details' => ['nullable', 'array'], // 先标记为数组类型 'details.*.product_id' => ['required', 'integer', 'exists:products,id'], 'details.*.product_collection_id' => [ 'nullable', 'integer', 'exists:product_collections,id', new ProductAndCollectionValidator(), ], // ...其他规则 ];
二、验证details数组中无重复的product_id+product_collection_id组合
新增一个自定义规则来校验组合唯一性:
1. 编写UniqueProductCollectionPair规则
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class UniqueProductCollectionPair implements Rule { public function passes($attribute, $value) { $seenPairs = []; foreach ($value as $item) { // 将product_id和collection_id转为唯一标识字符串,兼容null场景 $pairKey = json_encode([ 'product_id' => $item['product_id'], 'product_collection_id' => $item['product_collection_id'] ?? null ]); if (in_array($pairKey, $seenPairs)) { return false; // 发现重复组合 } $seenPairs[] = $pairKey; } return true; } public function message() { return '详情中存在重复的产品与集合组合'; } }
2. 绑定到details字段的验证规则
更新details字段的规则,添加该自定义规则:
'details' => ['nullable', 'array', new UniqueProductCollectionPair()],
最终完整验证规则示例
return [ 'amount' => ['nullable', 'numeric'], 'currency_id' => ['nullable', 'integer', Rule::in($allowedCurrencyIds)], 'details' => ['nullable', 'array', new UniqueProductCollectionPair()], 'details.*.product_id' => ['required', 'integer', 'exists:products,id'], 'details.*.product_collection_id' => [ 'nullable', 'integer', 'exists:product_collections,id', new ProductAndCollectionValidator(), ], // ...其他规则 ];
内容的提问来源于stack exchange,提问作者Hilal Najem
相关产品推荐
相关产品推荐

