Laravel数组验证时如何获取当前项索引并传递对应owner_id到自定义规则
你原来的写法失效的原因是 request()->input('items.myarray.*.owner_id') 返回的是所有数组项的owner_id组成的集合,不是当前验证项对应的单独owner_id值,可通过以下两种方式解决:
方法1:动态生成验证规则
提前遍历输入的数组,为每一项单独拼接验证规则,直接获取对应索引的owner_id传入自定义规则:
// 初始化基础规则 $rules = [ 'items.myarray.*.owner_id' => 'numeric|exists:App\Models\Owner', ]; // 遍历数组生成每个key的专属规则 foreach (request()->input('items.myarray', []) as $index => $item) { $rules["items.myarray.{$index}.key"] = [ 'nullable', 'string', 'min:20', 'max:20', 'exists:App\Models\Invitation,key', new KeyIsValid(Owner::findOrFail($item['owner_id'])) ]; } // 后续直接使用$rules执行验证即可
方法2:自定义规则内自动匹配同项字段
修改KeyIsValid自定义规则,通过当前验证的字段路径提取索引,自动读取同项的owner_id,不需要在定义验证规则时手动传参,代码更简洁易复用:
首先修改KeyIsValid规则实现:
use Illuminate\Contracts\Validation\ValidationRule; class KeyIsValid implements ValidationRule { public function validate(string $attribute, mixed $value, \Closure $fail): void { // 替换字段后缀,拿到同项owner_id的字段名 $ownerIdField = preg_replace('/\.key$/', '.owner_id', $attribute); $ownerId = request()->input($ownerIdField); // 前置校验避免异常(上层已有owner_id的exists规则,可根据需求取舍) if (empty($ownerId) || !Owner::where('id', $ownerId)->exists()) { return; } $owner = Owner::findOrFail($ownerId); // 替换为你原本的验证逻辑 if (!$owner->checkKeyValid($value)) { $fail('该key与所属owner不匹配'); } } }
之后验证规则可以直接按原始写法定义即可:
[ 'items.myarray.*.owner_id' => 'numeric|exists:App\Models\Owner', 'items.myarray.*.key' => ['nullable', 'string', 'min:20', 'max:20', 'exists:App\Models\Invitation,key', new KeyIsValid()], ];
内容的提问来源于stack exchange,提问作者SPQRInc
相关产品推荐
相关产品推荐

