PHP批量插入异常:仅插入首行/未选中首行无数据插入
解决复选框选中行插入数据库的问题
看起来你遇到的问题是:只有选中表格第一行时数据能插入,没选第一行就完全没数据。这是因为你的复选框索引和表单数据数组的索引不匹配导致的,我来帮你一步步修复:
问题出在哪?
你当前的代码里,foreach($_POST['checked'] as $id=>$value)中的$id是复选框数组的自身索引(比如只选第二行时,这个索引是0),但你用它去取student_id[$id]、CA1[$id]这些数据时,对应的是表单数组的第0项(也就是第一行的数据),这就导致要么取错行,要么没数据。
修复步骤
1. 调整复选框的value为行索引
在表格循环生成行的时候,把复选框的value改成当前行的数组索引(从0开始),这样选中后就能直接用这个索引去取对应的数据:
原来的复选框代码:
<input type="checkbox" class="ace" name="checked[]" value="<?php echo $row['id'];?>" />
改成:
<input type="checkbox" class="ace" name="checked[]" value="<?php echo $cnt-1;?>" />
这里$cnt是你循环里的计数器(初始为1),$cnt-1刚好对应表单数组的索引(0,1,2...)。
2. 重写插入逻辑,匹配正确的索引
修改你的插入脚本,用选中的索引去获取对应行的所有数据,同时修复SQL拼接的问题(之前每次循环都追加SQL会导致重复执行):
<?php $enroll_sql = []; if(isset($_POST['add_assessment'])) { if(empty($_POST['checked'])){ echo '<script>alertify.alert("No Student is selected.",function(e){if(e){document.location.href = "cass_entry.php";}}).set("labels", {ok:"OK!"}).set("defaultFocus", "ok").set("title", "Assessment") </script>'; exit(); } // 先把公共参数提出来,不用每次循环都取 $session = $_POST['session']; $term = $_POST['term']; $c_taught = $_POST['c_taught']; $s_taught = $_POST['s_taught']; foreach($_POST['checked'] as $row_index) { // 通过选中的索引获取对应行的所有数据 $student_id = $_POST['student_id'][$row_index]; $student_name = $_POST['student_name'][$row_index]; $ca_1 = $_POST['CA1'][$row_index]; $ca_2 = $_POST['CA2'][$row_index]; $ca_3 = $_POST['CA3'][$row_index]; $exam = $_POST['Exam'][$row_index]; $total = $_POST['Total'][$row_index]; // 必须做SQL注入防护!这里用转义,更推荐用预处理语句 $session = mysqli_real_escape_string($conn, $session); $term = mysqli_real_escape_string($conn, $term); $c_taught = mysqli_real_escape_string($conn, $c_taught); $s_taught = mysqli_real_escape_string($conn, $s_taught); $student_id = mysqli_real_escape_string($conn, $student_id); $student_name = mysqli_real_escape_string($conn, $student_name); $ca_1 = mysqli_real_escape_string($conn, $ca_1); $ca_2 = mysqli_real_escape_string($conn, $ca_2); $ca_3 = mysqli_real_escape_string($conn, $ca_3); $exam = mysqli_real_escape_string($conn, $exam); $total = mysqli_real_escape_string($conn, $total); // 把每个插入语句存入数组,最后合并执行 $enroll_sql[] = "INSERT INTO tbl_subjects_enrollment (`Session`,`Term`,`Student_Class`,`Subject_Name`,`Student_ID`,`Student_Name`,`CA_1`,`CA_2`,`CA_3`,`Exam`,`Total`) VALUES('$session', '$term', '$c_taught', '$s_taught', '$student_id', '$student_name', '$ca_1', '$ca_2', '$ca_3', '$exam', '$total')"; } if(!empty($enroll_sql)){ $final_sql = implode('; ', $enroll_sql); if (mysqli_multi_query($conn, $final_sql)) { $success_msg = '<div class="alert alert-success"> <button type="button" class="close" data-dismiss="alert"> <i class="ace-icon fa fa-times"></i> </button> <h4><i class="ace-icon fa fa-check"> Success</i></h4> <p>Assessment scores were successfully saved.</p></div>'; } else { echo "Error saving Assessment: " . $conn->error; } } } ?>
额外提醒
- SQL注入风险:你的原始代码完全没有做输入过滤,很容易被攻击,上面的代码加了
mysqli_real_escape_string,但更推荐使用预处理语句(Prepared Statements),这是更安全的做法。 - 调试小技巧:如果还是有问题,可以在插入前加
var_dump($_POST),看看提交的所有数据,确认选中的索引和表单数据的索引是否对应。 - 表单数组一致性:确保生成表格时,所有
name="xxx[]"的输入框是按顺序生成的,不要打乱数组的索引顺序。
内容的提问来源于stack exchange,提问作者HardSoft
相关产品推荐
相关产品推荐

