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++; });
四、额外优化建议
- 自动计算总价:给
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); });
- 表单验证:提交前检查每一行的必填字段(比如产品编号、名称、单价、数量)是否为空
- 错误排查:PHP里可以加更详细的错误捕获,比如用
try-catch(如果改用PDO的话),或者打印$con->error快速定位问题
内容的提问来源于stack exchange,提问作者Gustaryana Putra
相关产品推荐
相关产品推荐

