PHP+SQLite答题系统分数页两类警告错误的修复方法
PHP答题系统警告修复方案
错误原因分析
第95行:Trying to access array offset on value of type null
提交最后一道题后,$currentQuestion已变为null,但POST处理代码仍尝试访问$currentQuestion['Correct'],触发数组偏移量访问错误。第103行:Undefined array key "questionIndex"
所有题目完成后,代码会执行unset($_SESSION['questionIndex']),若此时用户刷新页面或触发POST请求,访问未定义的session键就会抛出警告。
修复步骤
- 调整POST请求处理顺序:将POST逻辑移到session初始化和页面渲染之前,确保提交请求时能正确获取当前题目数据。
- 增加空值检查:访问
$currentQuestion的数组键前,先确认它不为null。 - session变量安全访问:读取session中的
questionIndex和score时,增加存在性检查,避免未定义键警告。
修复后的完整代码
<?php session_start(); class MyDB extends SQLite3 { function __construct() { $this->open('questions.db'); } } // 先处理POST提交请求 if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['submit'])) { // 确保session中的核心数据存在 if (isset($_SESSION['questions'], $_SESSION['questionIndex'], $_SESSION['score'])) { $questions = $_SESSION['questions']; $questionIndex = $_SESSION['questionIndex']; $currentQuestion = (!empty($questions) && $questionIndex < count($questions)) ? $questions[$questionIndex] : null; if ($currentQuestion !== null) { $userAnswer = isset($_POST['answer']) ? $_POST['answer'] : ''; $correctAnswer = $currentQuestion['Correct']; if ($userAnswer == $correctAnswer) { $_SESSION['score']++; } } // 移动到下一题,判断是否还有剩余题目 if ($_SESSION['questionIndex'] < count($_SESSION['questions']) - 1) { $_SESSION['questionIndex']++; } else { // 标记答题完成 $_SESSION['quizCompleted'] = true; } } // 重定向避免刷新重复提交 header("Location: " . $_SERVER['PHP_SELF']); exit(); } // 初始化session数据 $db = new MyDB(); if (!$db) { echo $db->lastErrorMsg(); } // 若未初始化题目或答题已完成,重置session并重新加载题目 if (!isset($_SESSION['questions']) || isset($_SESSION['quizCompleted'])) { unset($_SESSION["questions"]); unset($_SESSION['score']); unset($_SESSION['questionIndex']); unset($_SESSION['quizCompleted']); $sql = "SELECT * FROM questions"; $result = $db->query($sql); $_SESSION['questions'] = []; while ($row = $result->fetchArray(SQLITE3_ASSOC)) { $_SESSION['questions'][] = $row; } $_SESSION['score'] = 0; $_SESSION['questionIndex'] = 0; } // 准备当前题目数据 $questions = $_SESSION['questions']; $questionIndex = isset($_SESSION['questionIndex']) ? $_SESSION['questionIndex'] : 0; $currentQuestion = (!empty($questions) && $questionIndex < count($questions)) ? $questions[$questionIndex] : null; // 渲染页面内容 if ($currentQuestion !== null) { echo "<h1>" . $currentQuestion['QID'] . ") " . $currentQuestion['Stem'] . "</h1><br> "; echo "<form method='post'>"; echo "<input type='radio' name='answer' value='A'>" . $currentQuestion['Alt_A'] . "<br>"; echo "<input type='radio' name='answer' value='B'>" . $currentQuestion['Alt_B'] . "<br>"; echo "<input type='radio' name='answer' value='C'>" . $currentQuestion['Alt_C'] . "<br>"; echo "<input type='radio' name='answer' value='D'>" . $currentQuestion['Alt_D'] . "<br>"; echo "<button type='submit' name='submit'>Submit</button>"; echo "</form>"; } else { echo "<h2>Your Score: " . (isset($_SESSION['score']) ? $_SESSION['score'] : 0) . "</h2>"; // 添加重新答题按钮 echo "<form method='post'><button type='submit' name='submit'>Restart Quiz</button></form>"; } $db->close(); ?>
额外优化说明
- 增加POST重定向,解决页面刷新重复提交答案的问题。
- 添加
quizCompleted标记,确保答题完成后能正确重置session状态。 - 所有session变量访问均增加存在性检查,彻底消除未定义键警告。
内容的提问来源于stack exchange,提问作者Samitt
相关产品推荐
相关产品推荐

