每个Item_ID及其数据重复插入数据库4次的问题排查求助
问题:每个商品ID对应数据被重复插入数据库4次
当前遇到的问题是,每个Item_ID对应的订单数据会被重复插入数据库4次,且每条重复记录的quantity值不同,但对应商品是同一个。以下是原实现代码:
try { $user_id = $_SESSION['uid']; $sql = "SELECT * FROM items WHERE Item_ID IN (" . implode(',', $_SESSION['cart']) . ")"; $query = $pdo->query($sql); $orders = $query->fetchAll(PDO::FETCH_ASSOC); if ($orders > 0) { foreach ($orders as $order){ $item_id = $order['Item_ID']; $price = $order['Price']; $quantity = implode(', ', $_SESSION['qty_array']); $quantity_array = explode(', ', $quantity); foreach ($quantity_array as $qty) { $stmt = $pdo->prepare('INSERT INTO orders (user_id, item_id, name, email, phone, address, description, quantity, item_price, total_amount, payment_method) VALUES ( ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $stmt->execute([$user_id, $item_id, $name, $email, $phone, $address, $description, $qty, $price , $_SESSION['total'], $payment_method]); } } } } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
问题根源
问题出在以下代码段:
$quantity = implode(', ', $_SESSION['qty_array']); $quantity_array = explode(', ', $quantity);
在遍历每个商品的循环(foreach ($orders as $order))内部,每次都将整个$_SESSION['qty_array']转成字符串再拆分为数组,随后遍历这个完整的数量数组插入订单。这就导致每个商品都会和所有数量值配对插入——如果qty_array里有4个元素,每个商品就会被插入4次,对应不同的quantity值。
解决方案
核心是让商品ID与数量一一对应。因为$_SESSION['cart']存储的是商品ID数组,$_SESSION['qty_array']应该是对应每个商品ID的数量数组,两者索引位置是对应的。通过索引关联商品和其对应的数量即可解决重复插入问题:
修改后的代码
try { $user_id = $_SESSION['uid']; // 取出购物车ID数组和对应数量数组 $cart_ids = $_SESSION['cart']; $qty_array = $_SESSION['qty_array']; // 先校验两个数组长度一致,避免索引越界 if (!empty($cart_ids) && count($cart_ids) === count($qty_array)) { // 生成占位符,避免SQL注入风险 $placeholders = implode(',', array_fill(0, count($cart_ids), '?')); $sql = "SELECT * FROM items WHERE Item_ID IN ($placeholders)"; $stmt = $pdo->prepare($sql); $stmt->execute($cart_ids); $orders = $stmt->fetchAll(PDO::FETCH_ASSOC); // 遍历商品时,通过索引匹配对应的数量 foreach ($orders as $index => $order){ $item_id = $order['Item_ID']; $price = $order['Price']; // 直接取当前索引对应的数量,无需转字符串拆分 $qty = $qty_array[$index]; $insert_stmt = $pdo->prepare('INSERT INTO orders (user_id, item_id, name, email, phone, address, description, quantity, item_price, total_amount, payment_method) VALUES ( ? ,?, ?, ?, ?, ?, ?, ?, ?, ?, ?)'); $insert_stmt->execute([$user_id, $item_id, $name, $email, $phone, $address, $description, $qty, $price , $_SESSION['total'], $payment_method]); } } } catch (PDOException $e) { echo "Error: " . $e->getMessage(); }
额外说明
- 新增了
$_SESSION['cart']和$_SESSION['qty_array']的长度校验,避免索引越界报错; - 将SQL查询改为预处理语句,消除了直接拼接数组带来的SQL注入风险;
- 去掉了冗余的字符串转数组操作,直接通过索引关联商品与数量,确保每个商品只插入一次对应数量的订单。
内容的提问来源于stack exchange,提问作者D K
相关产品推荐
相关产品推荐

