Laravel验证中如何避免重复值?distinct验证规则失效问题求助
我来帮你搞定这个Laravel验证重复值的问题!你遇到的问题根源是误解了distinct规则的用途——Laravel自带的distinct默认是用来验证数据库字段唯一性的,不是用来检查请求数组内部的重复值,所以你之前写的distinct:versions.*.pattern根本不会生效。
下面给你两种实用的解决方案,按需选择:
方案一:用自定义验证闭包(快速解决,无需额外配置)
直接在验证逻辑里加一个闭包,手动检查versions数组里的pattern是否重复:
$request->validate([ 'versions' => 'array', 'versions.*.pattern' => ['string', 'required_with:modifiers'], // 新增闭包验证重复值 'versions' => function ($attribute, $value, $fail) { // 提取所有非空的pattern值 $patterns = collect($value) ->pluck('pattern') ->filter() // 过滤掉空值(因为required_with可能让部分元素无pattern) ->toArray(); // 比较原长度和去重后的长度,不一致说明有重复 if (count($patterns) !== count(array_unique($patterns))) { $fail('所有版本的pattern值不能重复,请检查后重试。'); } }, ]);
方案二:自定义可复用的验证规则(适合多次使用场景)
如果你的项目里多处需要验证数组嵌套字段的唯一性,可以自定义一个规则,以后直接调用:
- 打开
app/Providers/AppServiceProvider.php,在boot方法里注册自定义规则:
use Illuminate\Support\Facades\Validator; public function boot() { Validator::extend('unique_in_array', function ($attribute, $value, $parameters, $validator) { // 从字段名中解析出父数组的名称(比如从versions.*.pattern得到versions) $arrayAttribute = str_replace('.*.'.$parameters[0], '', $attribute); $array = $validator->getData()[$arrayAttribute] ?? []; // 提取并过滤目标字段的值 $values = collect($array) ->pluck($parameters[0]) ->filter() ->toArray(); return count($values) === count(array_unique($values)); }); // 可选:自定义错误消息 Validator::replacer('unique_in_array', function ($message, $attribute, $parameters) { return str_replace(':field', $parameters[0], '数组中的:field值不能重复'); }); }
- 然后在验证规则里直接使用这个自定义规则:
$request->validate([ 'versions.*.pattern' => [ 'string', 'required_with:modifiers', 'unique_in_array:pattern' // 调用自定义规则 ], ]);
这样以后任何需要验证数组嵌套字段唯一性的场景,都可以直接用unique_in_array:字段名了。
内容的提问来源于stack exchange,提问作者Kian Sadeghi
相关产品推荐
相关产品推荐

