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

PHP MySQL发票多行数据插入功能实现技术求助

解决PHP批量插入多行发票数据到MySQL的问题

嘿,你的多行插入思路是对的,但现有代码有两个关键问题得修正:严重的SQL注入风险和潜在的SQL语法错误,另外前端还有个小细节要统一。我来一步步帮你优化:

一、现有代码的核心问题

你直接把用户输入的变量拼进SQL语句里,这太危险了——要是有人输入恶意内容(比如' OR 1=1 --),分分钟就能篡改你的数据库。而且如果产品名称里带单引号(比如O'Neil),会直接导致SQL语法报错,插入失败。

二、优化后的PHP插入代码(用预处理语句)

我们用MySQLi的预处理语句来解决安全问题,同时保证语法稳定:

// 先确保表单提交的数组都存在
if(isset($_POST['itemNo'], $_POST['itemName'], $_POST['price'], $_POST['quantity'], $_POST['total'])) {
    $idproduk = $_POST['itemNo'];
    $namaproduk = $_POST['itemName'];
    $harga = $_POST['price'];
    $qty = $_POST['quantity'];
    $sub = $_POST['total'];
    
    // 校验所有数组长度一致,避免数据缺失
    $count = count($idproduk);
    if(count($namaproduk) != $count || count($harga) != $count || count($qty) != $count || count($sub) != $count) {
        die("数据不完整,请检查所有行的输入内容");
    }

    // 准备预处理语句,用占位符代替实际值
    $insertSql = "INSERT INTO subtrans (idproduk, namaproduk, harga, qty, sub) VALUES (?, ?, ?, ?, ?)";
    $stmt = $con->prepare($insertSql);
    
    // 绑定参数类型:s=字符串,i=整数,d=浮点数(根据你的数据库字段类型调整)
    // 这里假设idproduk是字符串、namaproduk是字符串、harga是浮点数、qty是整数、sub是浮点数
    $stmt->bind_param("ssdis", $pid, $pname, $price, $quantity, $total);

    // 循环插入每一行数据
    for ($i=0; $i < $count; $i++) { 
        // 先过滤和验证数据(按需调整规则)
        $pid = trim($idproduk[$i]);
        $pname = trim($namaproduk[$i]);
        $price = floatval($harga[$i]);
        $quantity = intval($qty[$i]);
        $total = floatval($sub[$i]);

        // 执行当前行插入,出错时提示具体信息
        if(!$stmt->execute()) {
            echo "插入第".($i+1)."行失败:".$stmt->error;
            break;
        }
    }

    // 清理资源
    $stmt->close();
    echo "成功插入".$count."条发票明细数据";
} else {
    die("未接收到表单提交的数据");
}

为什么用预处理?

  • 彻底杜绝SQL注入:占位符会自动转义特殊字符,不用手动处理
  • 语法更可靠:不用担心单引号、换行符等破坏SQL结构
  • 性能更优:预处理语句只编译一次,循环执行多次效率更高

三、前端代码的小修正

你初始HTML里的price和quantity是type="number",但JS添加新行时写成了type="text",这会导致输入类型不一致,建议统一改成number:

//adds extra table rows
var i=$('table tr').length;
$(".addmore").on('click',function(){
    html = '<tr>';
    html += '<td><input class="case" type="checkbox"/></td>';
    html += '<td><input type="text" data-type="idproduk" name="itemNo[]" id="itemNo_'+i+'" class="form-control form-control-sm autocomplete_txt" autocomplete="off"></td>';
    html += '<td><input type="text" data-type="namaproduk" name="itemName[]" id="itemName_'+i+'" class="form-control form-control-sm autocomplete_txt" autocomplete="off"></td>';
    // 这里把type改回number,和初始行保持一致
    html += '<td><input type="number" name="price[]" id="price_'+i+'" class="form-control form-control-sm changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;"onpaste="return false;"></td>';
    html += '<td><input type="number" name="quantity[]" id="quantity_'+i+'" class="form-control form-control-sm changesNo" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '<td><input type="number" name="total[]" id="total_'+i+'" class="form-control form-control-sm totalLinePrice" autocomplete="off" onkeypress="return IsNumeric(event);" ondrop="return false;" onpaste="return false;"></td>';
    html += '</tr>';
    $('table').append(html);
    i++;
});

四、额外优化建议

  1. 自动计算总价:给price和quantity加onchange事件,自动计算total,避免手动输入错误:
$(document).on('change', '.changesNo', function(){
    var row = $(this).closest('tr');
    var price = parseFloat(row.find('[name="price[]"]').val()) || 0;
    var qty = parseInt(row.find('[name="quantity[]"]').val()) || 0;
    row.find('[name="total[]"]').val(price * qty);
});
  1. 表单验证:提交前检查每一行的必填字段(比如产品编号、名称、单价、数量)是否为空
  2. 错误排查:PHP里可以加更详细的错误捕获,比如用try-catch(如果改用PDO的话),或者打印$con->error快速定位问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:24:39