PHP多选题测验表单提交后参数获取失败且数据库无更新问题求助
问题根因
- 前端循环输出问题时未给
$quiz_question_id变量赋值就直接调用,导致复选框name属性的键值为空,无法关联问题ID - 全局唯一的
quiz_assign_id隐藏域放在循环内重复输出,且所有问题的quiz_question_id隐藏域使用相同name,最终提交时只会保留最后一条的值 - 后端遍历
$_POST['Response']时只取了作答值,没有取数组的键(即关联的问题ID) - 多选场景下同个问题的复选框name没有加
[],会导致同个问题选多个选项时只提交最后一个选中的值
解决方案
一、前端代码修改
- 把全局
quiz_assign_id隐藏域移到while循环外,避免重复输出 - 循环内给
$quiz_question_id赋值,删除循环内重复的quiz_assign_id和quiz_question_id隐藏域 - 多选场景下复选框name加
[],如果是单选题建议改为radio类型
修改后的前端代码如下:
<div class="Main"> <form method="post" action="LP_Quiz_Student_Quiz_Responses.php"> <!-- 全局唯一的quiz_assign_id隐藏域移到循环外 --> <input name="quiz_assign_id" type="hidden" value="<?php echo trim($_GET['quiz_assign_id']); ?>" /> <?php $quiz_id = trim($_GET['quiz_id']); $quiz_assign_id = trim($_GET['quiz_assign_id']); $i = 1; $sel_query=("SELECT Quiz.quiz_id, Quiz.quiz_title, Quiz_Questions.quiz_id, Quiz_Questions.quiz_question_id, Quiz_Questions.question, Quiz_Questions.option1, Quiz_Questions.option2, Quiz_Questions.option3, Quiz_Questions.answer FROM Quiz, Quiz_Questions WHERE (Quiz.quiz_id=Quiz_Questions.quiz_id) and (Quiz.quiz_id=?)"); $stmt = $conn->prepare($sel_query); $stmt->bind_param("i", $quiz_id); $stmt->execute(); $result = $stmt->get_result(); if($result->num_rows === 0) exit('No Quiz Questions!'); while($row = $result->fetch_assoc()) { // 新增赋值操作 $quiz_question_id = $row["quiz_question_id"]; ?> <p> </p> <table> <tr> <td> <h4>Question <?php echo $i++; ?> </h4> </td> <td> <h4><?php echo $row["question"]; ?> </h4> </td> <td> </td> </tr> <tr> <td> <h4>A</h4> </td> <td><?php echo $row["option1"]; ?> </td> <td> <!-- 多选加[],单选改成type="radio"即可 --> <input name="Response[<?php echo $quiz_question_id; ?>][]" type="checkbox" value="Option A" style="width: 20px" /> </td> </tr> <tr> <td> <h4>B</h4> </td> <td><?php echo $row["option2"]; ?> </td> <td> <input name="Response[<?php echo $quiz_question_id; ?>][]" type="checkbox" value="Option B" /> </td> </tr> <tr> <td> <h4>C</h4> </td> <td><?php echo $row["option3"]; ?> </td> <td> <input name="Response[<?php echo $quiz_question_id; ?>][]" type="checkbox" value="Option C" /> </td> </tr> </table> <?php } ?> <input name="Submit1" type="submit" value="submit" /> </form> </div>
二、后端代码修改
- 遍历
$_POST['Response']时同时取键(问题ID)和值(作答内容) - 多选场景下把作答数组拼接为字符串存储,也可按需求序列化存储
- 调整跳转逻辑,等所有数据处理完再跳转
修改后的后端代码如下:
<?php if(!empty($_POST['Response']) && !empty($_POST['quiz_assign_id'])) { $quiz_assign_id = trim($_POST['quiz_assign_id']); $update_success = false; // 遍历同时取key和value,key就是问题ID foreach ($_POST['Response'] as $quiz_question_id => $response_arr) { // 多选场景把选项拼接为逗号分隔的字符串 $response = implode(',', $response_arr); echo 'Answer:'.$response; echo ' Question:'.$quiz_question_id; echo ' Student ID:'.$quiz_assign_id.' successfully assigned! <br>'; $stmt = $conn->prepare('UPDATE Quiz_Assign_Student_Question SET response = ? WHERE quiz_assign_id = ? and quiz_question_id =? '); if ( $stmt && $stmt->bind_param('sss', $response, $quiz_assign_id, $quiz_question_id) && $stmt->execute() ) { $update_success = true; } } // 所有数据处理完再跳转 if($update_success) { echo "<script> alert('Responses submitted!'); window.history.go(-2); </script>"; } else { echo "<script> alert('提交失败,请重试'); window.history.go(-2); </script>"; } } ?>
注:如果题目为单选题,可把前端复选框改为
type="radio",同时去掉name后的[],后端无需implode处理,直接取$response_arr作为作答值即可。
内容的提问来源于stack exchange,提问作者Python Help
相关产品推荐
相关产品推荐

