如何在Laravel表单验证中确保多个banner优先级输入值不重复?
需求说明
需要确保表单提交的banner_one_priority、banner_two_priority、banner_three_priority、banner_four_priority、banner_five_priority这五个字段的数值(限定1-5)互不重复,任何两个字段不能使用相同的优先级数值。
解决方案
可以通过集合唯一性检查结合Laravel的验证机制实现,同时优化数据库操作代码减少冗余:
修改后的Controller代码
use Illuminate\Validation\ValidationException; public function updateBannerPriorities(Request $request, $id) { // 基础字段验证:必填、数值范围1-5 $data = $request->validate([ 'banner_one_priority' => 'required|digits_between:1,5', 'banner_two_priority' => 'required|digits_between:1,5', 'banner_three_priority' => 'required|digits_between:1,5', 'banner_four_priority' => 'required|digits_between:1,5', 'banner_five_priority' => 'required|digits_between:1,5', ], [], [ // 自定义字段友好名称,方便错误提示 'banner_one_priority' => 'Banner 1 优先级', 'banner_two_priority' => 'Banner 2 优先级', 'banner_three_priority' => 'Banner 3 优先级', 'banner_four_priority' => 'Banner 4 优先级', 'banner_five_priority' => 'Banner 5 优先级', ]); // 检查所有优先级是否唯一 $priorities = collect([ $data['banner_one_priority'], $data['banner_two_priority'], $data['banner_three_priority'], $data['banner_four_priority'], $data['banner_five_priority'], ]); if ($priorities->count() !== $priorities->unique()->count()) { throw ValidationException::withMessages([ 'banner_one_priority' => '所有Banner优先级必须互不重复', ]); } // 优化数据库批量更新,减少重复代码 $bannerFieldMap = [ 'spf_home_banner1' => $data['banner_one_priority'], 'spf_home_banner2' => $data['banner_two_priority'], 'spf_home_banner3' => $data['banner_three_priority'], 'spf_home_banner4' => $data['banner_four_priority'], 'spf_home_banner5' => $data['banner_five_priority'], ]; foreach ($bannerFieldMap as $fieldName => $priority) { DB::table('static_pages_field') ->where('spf_page_type', 'slider') ->where('spf_field_name', $fieldName) ->update(['spf_field_value' => $priority]); } return redirect()->back(); }
关键实现说明
- 基础验证:先确保每个字段都是必填且数值在1-5之间,符合业务基础要求。
- 唯一性检查:通过Laravel集合的
unique()方法,对比原始集合长度与去重后的长度,判断是否存在重复值。如果存在重复,抛出ValidationException返回错误提示。 - 代码优化:将重复的数据库更新逻辑通过遍历关联数组实现,减少冗余代码,提升可维护性。
可选进阶方案:自定义验证规则
如果需要在多个地方复用该验证逻辑,可以创建自定义验证规则:
- 创建规则类:
php artisan make:rule UniqueBannerPriorities
- 编写规则逻辑:
<?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; class UniqueBannerPriorities implements Rule { public function passes($attribute, $value) { $priorities = request()->only([ 'banner_one_priority', 'banner_two_priority', 'banner_three_priority', 'banner_four_priority', 'banner_five_priority', ]); return collect($priorities)->count() === collect($priorities)->unique()->count(); } public function message() { return '所有Banner优先级必须互不重复'; } }
- 在控制器中使用:
$data = $request->validate([ 'banner_one_priority' => ['required', 'digits_between:1,5', new UniqueBannerPriorities], // 其他字段可省略该规则,因为自定义规则会检查所有目标字段 ]);
内容的提问来源于stack exchange,提问作者Pouya Vaghefi
相关产品推荐
相关产品推荐

