HTML表单提交时如何匹配对应questionID插入answers数据表
调研系统答案存储问题修复方案
现有代码核心问题
- 表单渲染时未给每道题绑定唯一ID标识,所有答案输入框的name均为
answer,提交后后端无法区分答案对应哪道题目 getQuestionName()逻辑存在缺陷:全量查询问题表后直接返回第一条数据的questionID,永远无法匹配当前用户提交答案对应的题目- 参数绑定类型不匹配:
questionID为整型字段,绑定时误用字符串类型s,存在数据写入异常隐患 - 跳转逻辑不严谨:执行
header跳转后未终止程序,后续代码仍会执行,可能引发非预期行为 - 未做输出转义:直接从数据库取出问题内容输出到HTML,存在XSS安全风险
修复实现
1. 调整表单渲染函数
在每道题的表单中增加隐藏域,存储当前题目对应的questionID,提交时随答案内容一起传给后端,同时对输出的问题内容做转义处理:
function getQuestions($connect) { $query = "SELECT questionID, questionBody FROM questions"; $result = mysqli_query($connect, $query); if ($result) { while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { $qid = $row['questionID']; // 转义特殊字符,避免XSS注入 $body = htmlspecialchars($row['questionBody']); echo '<div class="entry"> <div class="questionTitle"><h3>' . $body . '</h3> <form action="survey.php" method="POST"> <!-- 隐藏域携带当前题目的ID,提交时随答案上传 --> <input type="hidden" name="questionID" value="' . $qid . '" /> <input type="text" name="answer" size="50" /> <input type="submit" value="提交答案" name="submit" /> </form> </div> </div>'; } } }
2. 移除无效的getQuestionName()函数,重写提交处理逻辑
直接从POST请求参数中获取前端传递的questionID,增加参数合法性校验,修正参数绑定类型,补充跳转后的程序终止逻辑:
$answerError = ""; // 校验是否为合法提交请求 if ($_SERVER["REQUEST_METHOD"] === "POST" && isset($_POST["submit"])) { // 校验答案内容 $answer = trim($_POST["answer"] ?? ""); if (empty($answer)) { $answerError = "答案不能为空"; } // 校验题目ID合法性 $paramQuestion = intval($_POST["questionID"] ?? 0); if ($paramQuestion <= 0) { $answerError = "题目参数无效"; } if (empty($answerError)) { $sql = "INSERT INTO answers (questionID, answerBody) VALUES (?,?)"; if ($statement = mysqli_prepare($connect, $sql)) { // questionID为整型,对应类型标识i;answerBody为字符串,对应类型标识s mysqli_stmt_bind_param($statement, "is", $paramQuestion, $paramAnswer); $paramAnswer = $answer; if (mysqli_stmt_execute($statement)) { header("location: thankyou.php"); // 跳转后终止后续代码执行 exit(); } else { echo "系统异常,请稍后重试"; } mysqli_stmt_close($statement); } } mysqli_close($connect); }
可选优化:单表单批量提交所有答案
如果需要用户填完所有题目后一次性提交,可以把表单标签移到题目循环外部,将答案输入框的名称设置为带questionID的数组格式,减少提交次数:
function getQuestions($connect) { $query = "SELECT questionID, questionBody FROM questions"; $result = mysqli_query($connect, $query); if ($result) { // 表单起始标签放在循环外 echo '<form action="survey.php" method="POST">'; while ($row = mysqli_fetch_array($result, MYSQLI_ASSOC)) { $qid = $row['questionID']; $body = htmlspecialchars($row['questionBody']); echo '<div class="entry"> <div class="questionTitle"><h3>' . $body . '</h3> <!-- 输入框name用数组形式,key为对应questionID --> <input type="text" name="answers['.$qid.']" size="50" /> </div> </div>'; } // 提交按钮放在所有题目之后 echo '<input type="submit" value="提交所有答案" name="submitAll" /> </form>'; } }
后端接收到answers数组后,遍历数组循环执行插入即可,数组的键就是对应题目的questionID,值为用户填写的答案内容。
内容的提问来源于stack exchange,提问作者EpicTeddy101
相关产品推荐
相关产品推荐

