Laravel 同分组条件下name数组字段唯一性校验失效问题修复
问题根源
原有校验逻辑存在规则绑定粒度不匹配的问题,直接导致多值场景下校验失效:
- 单值提交时,
name字段是普通字符串结构,绑在name根节点的规则会直接对传入的单个值做数据库比对,因此校验能正常工作 - 多值提交时,通过
name[]结构传入的是PHP数组类型,绑在name根节点的规则只会将数组整体作为值传给校验逻辑,由于数据库name字段是普通字符串类型,永远无法匹配数组结构的入参,因此唯一性校验直接失效,不会自动下沉到数组内部的每个元素执行校验。
修复方案
需要调整规则的绑定层级,将面向单值的校验(必填、带分组条件的唯一性)下沉到数组的每一个子项上,同时保留对name数组整体的合法性校验:
- 对
name根节点做数组类型、非空校验,确保提交结构合法 - 对
name.*(数组所有子项)逐一应用必填、同分组下数据库唯一性校验,可附加提交值内部去重规则,避免同一次提交内出现重复name值
调整后可直接运行的校验代码
use Illuminate\Validation\Rule; // 表单校验逻辑 $validated = $request->validate([ // 分组字段基础校验 'group' => 'required|string', // name数组整体校验:必须存在、必须是数组类型 'name' => 'required|array', // 对数组内每个name值逐一应用校验 'name.*' => [ 'required', 'string', // 可选增强:校验本次提交的name数组内部不能有重复值 Rule::distinct(), // 同分组下的数据库唯一性校验 Rule::unique('group_tbl', 'name')->where(function ($query) use ($request) { $query->where('group', $request->input('group')); }) ] ]);
修复效果验证
按照原有复现场景测试:
- 数据库已存在记录(id=1, group=G, name=A)
- 提交group值为G、name数组为[A,B]时,校验会逐个遍历数组元素:
- 第一个元素A,会匹配到同分组下的数据库已有记录,自动触发唯一性错误,错误会绑定在对应数组索引的字段上(即
name.0) - 第二个元素B,不存在同分组下的重复记录,校验通过
- 第一个元素A,会匹配到同分组下的数据库已有记录,自动触发唯一性错误,错误会绑定在对应数组索引的字段上(即
- 提交group值为G、name数组为[B,C]时,所有元素都无数据库重复,校验通过
注意事项
如果是编辑场景需要排除当前正在修改的记录,只需要在unique规则后链式追加->ignore($当前记录ID, 'id')即可,避免编辑时自身值触发重复校验。
内容的提问来源于stack exchange,提问作者Amrita Stha
相关产品推荐
相关产品推荐

