Laravel验证:禁止订单中重复选择同一商品
订单重复商品验证问题解决
问题场景
需要实现订单多商品的重复验证,确保单个订单中不能选择同一商品。从请求数据可以看到,product_id0和product_id1的值均为1,属于重复商品,但现有验证逻辑无法正确检测,甚至在商品ID不同时仍返回错误提示。
请求数据示例:
+request: Symfony\Component\HttpFoundation\InputBag {#45 #parameters: array:16 [ "_token" => "El3iq45CsoEPRXxwaAOv072O0bWARb5WUNx3Lmfe" "warehouse_id" => "1" "customer_id" => "1" "order_date" => "2023-08-24 19:20" "shipping_address" => "q" "product_id0" => "1" "qty0" => "1" "stock_outstanding0" => "99" "unit_price0" => "65000" "total_price0" => "65000" "count_item" => "1" "product_id1" => "1" "qty1" => "1" "stock_outstanding1" => "100" "unit_price1" => "65000" "total_price1" => "65000" ] }
错误的验证逻辑
第一种错误实现
$isValid = true; for ($g = 0; $g <= $request->count_item; $g++) { $validator = Validator::make($request->all(), [ 'warehouse_id' => 'required', 'customer_id' => 'required', 'order_date' => 'required', 'shipping_address' => 'required', "product_id{$g}.*" => 'distinct', ]); if ($validator->fails()) { $isValid = false; break; } } if ($isValid) { return response()->json([ 'status' => true, 'message' => 'Validation Work', ]); } else { return response()->json([ 'status' => false, 'message' => 'Validation Failed', ]); }
第二种错误实现
$tempId = []; $tempArray = []; for ($g=0; $g <= $request->count_item; $g++) { $tempId[] = $request['product_id' . $g]; if(in_array($tempId, $tempArray)){ return response()->json([ 'status' => true, 'message' => 'True validation work', ]); }else{ return response()->json([ 'status' => false, 'message' => 'False validation failed', ]); $tempArray[] = $tempId; dd($tempArray); exit; } }
正确的解决方案
方案1:使用Laravel验证器distinct规则(推荐)
先收集所有商品ID为数组,再针对数组验证唯一性:
// 收集所有商品ID $productIds = []; for ($g = 0; $g <= $request->count_item; $g++) { $productIds[] = $request->input("product_id{$g}"); } // 构建验证规则 $validator = Validator::make( array_merge($request->all(), ['product_ids' => $productIds]), [ 'warehouse_id' => 'required', 'customer_id' => 'required', 'order_date' => 'required', 'shipping_address' => 'required', 'product_ids' => 'array|distinct', ] ); if ($validator->fails()) { return response()->json([ 'status' => false, 'message' => '订单中存在重复商品,请检查后重新提交', 'errors' => $validator->errors() ]); } return response()->json([ 'status' => true, 'message' => '验证通过' ]);
方案2:手动遍历检测重复
$productIds = []; $hasDuplicate = false; // 检测重复商品ID for ($g = 0; $g <= $request->count_item; $g++) { $currentId = $request->input("product_id{$g}"); if (in_array($currentId, $productIds)) { $hasDuplicate = true; break; } $productIds[] = $currentId; } // 验证必填字段 $requiredValidator = Validator::make($request->all(), [ 'warehouse_id' => 'required', 'customer_id' => 'required', 'order_date' => 'required', 'shipping_address' => 'required', ]); if ($requiredValidator->fails()) { return response()->json([ 'status' => false, 'message' => '必填字段不能为空', 'errors' => $requiredValidator->errors() ]); } if ($hasDuplicate) { return response()->json([ 'status' => false, 'message' => '订单中存在重复商品,请检查后重新提交' ]); } return response()->json([ 'status' => true, 'message' => '验证通过' ]);
错误原因分析
- 第一种错误逻辑:循环中单次验证单个
product_id{g}的distinct规则,但distinct是针对数组的校验规则,单个字段使用该规则不会生效,导致无论是否重复都判定验证通过。 - 第二种错误逻辑:循环第一次就直接返回结果,未遍历全部商品ID;且
in_array($tempId, $tempArray)是将数组作为元素查找,逻辑错误,应直接比较单个商品ID是否已存在。
内容的提问来源于stack exchange,提问作者Alberiansyah
相关产品推荐
相关产品推荐

