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

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' => '验证通过'
]);

错误原因分析

  1. 第一种错误逻辑:循环中单次验证单个product_id{g}的distinct规则,但distinct是针对数组的校验规则,单个字段使用该规则不会生效,导致无论是否重复都判定验证通过。
  2. 第二种错误逻辑:循环第一次就直接返回结果,未遍历全部商品ID;且in_array($tempId, $tempArray)是将数组作为元素查找,逻辑错误,应直接比较单个商品ID是否已存在。

内容的提问来源于stack exchange,提问作者Alberiansyah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 10:55:54