You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel中如何验证数组字段组合符合数据库联合唯一约束?

Laravel 数组参数多字段联合唯一校验实现方法

方法1:动态构建验证规则

一次性生成所有索引对应的验证规则,避免循环调用验证方法:

// 初始化基础规则
$rules = [
    'day.*.day' => ['required'],
    'time.*.start_time' => ['required', 'different:time.*.end_time'],
    'time.*.end_time' => ['required', 'different:time.*.start_time'],
];

// 遍历所有提交的时间条目索引,追加联合唯一规则
$timeList = request()->input('time', []);
foreach (range(0, count($timeList) - 1) as $index) {
    $rules["day.$index.day"][] = Rule::unique('days')
        ->where('day', request("day.$index.day"))
        ->where('start_time', request("time.$index.start_time"))
        ->where('end_time', request("time.$index.end_time"));
    // 如果是更新场景,需要忽略当前已存在的记录,添加以下代码
    // ->ignore(request("id.$index.id"));
}

// 执行统一校验
$validated = request()->validate($rules);

方法2:使用闭包规则(更灵活,支持自定义错误提示)

直接在通配符规则内通过闭包处理每个索引的唯一性校验:

use Illuminate\Support\Facades\DB;

$validated = request()->validate([
    'day.*.day' => [
        'required',
        function ($attribute, $value, $fail) {
            // 提取当前条目的索引
            $index = explode('.', $attribute)[1];
            $startTime = request("time.$index.start_time");
            $endTime = request("time.$index.end_time");
            
            // 查询数据库是否存在重复组合
            $exists = DB::table('days')
                ->where('day', $value)
                ->where('start_time', $startTime)
                ->where('end_time', $endTime)
                // 更新场景下添加忽略当前记录的条件
                // ->where('id', '!=', request("id.$index.id"))
                ->exists();
            
            if ($exists) {
                $fail('第'.($index + 1).'组时间配置已存在,请勿重复提交');
            }
        }
    ],
    'time.*.start_time' => ['required', 'different:time.*.end_time'],
    'time.*.end_time' => ['required', 'different:time.*.start_time'],
]);

注意事项

  • 原规则中的different:time.*.end需修正为different:time.*.end_time,保证和提交的字段名匹配。
  • 如果需要校验提交的参数内部是否存在重复组合(未入库就重复),可以额外在闭包内收集所有组合的哈希值,判断是否有重复。
  • 不要在循环内调用request()->validate(),每次验证失败都会直接抛出异常,无法完成全量校验。

内容的提问来源于stack exchange,提问作者I-dont-know-

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 05:54:08