Laravel验证:如何仅对同级数组元素执行distinct校验
解决Laravel验证中数组内元素单独校验唯一性的问题
问题分析
你当前的验证规则中,bla.*.* 上的 distinct 规则会将所有子数组的元素放在一起校验唯一性,导致跨子数组的重复值(比如第一个子数组的3和第二个子数组的3)也被判定为错误,不符合“仅校验单个内部数组元素唯一性”的需求。
解决方案一:使用内置distinct规则的作用域参数
Laravel的distinct规则支持通过参数限定校验的作用域,只需给distinct规则添加*.参数,即可让校验仅作用于当前元素的直接父数组(也就是每个子数组内部):
$data = [ [1, 2, 3], [3, 4, 5] ]; $validator = \Validator::make([ "bla" => $data, ], [ 'bla' => 'required|array', 'bla.*' => 'required|array|max:5|min:1', 'bla.*.*' => 'required|integer|distinct:*.', ]); if ($validator->fails()) { // 处理验证失败逻辑 }
解决方案二:自定义验证规则(更灵活)
如果内置规则的参数无法满足更复杂的需求,可以自定义规则专门校验单个数组内部的元素唯一性:
- 创建自定义规则类
namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class DistinctWithinArray implements Rule { public function passes($attribute, $value) { // 对比数组原始长度和去重后的长度,判断是否有重复 return count($value) === count(array_unique($value)); } public function message() { return 'The :attribute array contains duplicate values.'; } }
- 在验证逻辑中使用自定义规则
use App\Rules\DistinctWithinArray; $data = [ [4, 4, 3], [3, 8, 5] ]; $validator = \Validator::make([ "bla" => $data, ], [ 'bla' => 'required|array', 'bla.*' => ['required', 'array', 'max:5', 'min:1', new DistinctWithinArray()], 'bla.*.*' => 'required|integer', ]); if ($validator->fails()) { // 处理验证失败逻辑 }
效果验证
- 对于
[[1,2,3],[3,4,5]]:两个子数组内部元素均唯一,验证通过。 - 对于
[[4,4,3],[3,8,5]]:第一个子数组存在重复元素,验证失败并抛出对应错误。
内容的提问来源于stack exchange,提问作者Hey
相关产品推荐
相关产品推荐

