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

使用PDO时如何处理for循环内输入为空的错误问题

问题修复方案

存在的核心问题

  • 未提前校验$name数组是否为空,当传入的商品列表为空时,for循环直接跳过无执行逻辑,自然无返回结果
  • $stmt1仅在循环的插入分支中定义,若所有循环项都不满足插入条件,末尾判断$stmt1时会报未定义变量错误
  • 循环空跑时仍会执行账单表插入逻辑,会生成无对应商品的无效订单
  • 预处理SQL直接拼接变量,存在SQL注入风险
  • 订单号生成逻辑存在并发重复风险
  • 单条商品校验不通过就直接抛出错误,未处理批量场景下的异常终止逻辑

修复后的代码

public function Add_new_order($tableno, $cashier_name, $date, $time, $name, $quantity, $price, $sub_total, $total) {
    // 先校验传入的商品数组是否为空
    if(empty($name) || !is_array($name) || count($name) == 0) {
        $this->Error_msg('商品列表不能为空');
        return;
    }

    // 用事务包裹操作避免数据不一致,加行锁解决订单号并发重复问题
    $this->conn->beginTransaction();
    try {
        $stmt = $this->conn->prepare("SELECT MAX(order_num) AS order_number FROM all_orders FOR UPDATE");
        $stmt->execute(); 
        $row = $stmt->fetch();
        $order_num = $row["order_number"] ?? '100000';
        if(is_numeric($order_num)) {
            $order_num += 1;
        }

        $insert_count = 0;
        // 提前计算数组长度避免循环重复计算
        $item_count = count($name);
        for($i = 0; $i < $item_count; $i++) {   
            // 提前判断下标是否存在避免数组越界报错
            if(!isset($quantity[$i]) || !isset($name[$i]) || !isset($price[$i]) || !isset($sub_total[$i])) {
                continue;
            }
            if($quantity[$i] > 0 && $name[$i] != "" && $price[$i] != "") {
                // 用参数绑定彻底避免SQL注入
                $stmt1 = $this->conn->prepare("INSERT INTO `all_orders` (`order_num`, `tablenum`,`cashier_name`, `date`, `time`, `item_name`, `quantity`, `price`, `total`) VALUES (?,?,?,?,?,?,?,?,?)");
                $stmt1->execute([
                    $order_num,
                    $tableno,
                    $cashier_name,
                    $date,
                    $time,
                    $name[$i],
                    $quantity[$i],
                    $price[$i],
                    $sub_total[$i]
                ]);
                if($stmt1->rowCount() > 0) {
                    $insert_count++;
                }
            }
        }

        // 没有成功插入任何商品直接回滚报错
        if($insert_count == 0) {
            $this->conn->rollBack();
            $this->Error_msg('没有有效商品可插入');
            return;
        }

        // 插入账单表
        $stmt2 = $this->conn->prepare("INSERT INTO `biling`(`order_num`, `tablenum`,`cashier_name`, `date`, `time`, `total`) VALUES (?,?,?,?,?,?)");
        $stmt2->execute([
            $order_num,
            $tableno,
            $cashier_name,
            $date,
            $time,
            $total
        ]);

        if($stmt2->rowCount() > 0) {
            $this->conn->commit();
            $this->Success_msg('Done.');
        } else {
            $this->conn->rollBack();
            $this->Error_msg('账单插入失败');
        }
    } catch (Exception $e) {
        $this->conn->rollBack();
        $this->Error_msg('Error occurred:'.$e->getMessage());
    }
}

额外说明

  • 修复后新增了前置空数组校验,空输入时会直接返回错误提示
  • 用事务包裹整个操作,避免部分插入成功部分失败导致的数据不一致
  • 所有SQL改用参数绑定,彻底避免SQL注入风险
  • 新增插入成功计数校验,没有有效商品插入时不会生成空账单
  • 自增主键ID无需在插入语句中声明,数据库会自动生成

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:06:03