PHP测验Session计分漏洞:页面重载未重置分数的修复问询
修复测验页面刷新漏洞&代码优化建议
首先,咱们先解决你遇到的核心问题:页面刷新后回到第一题但分数保留的漏洞,以及你写的分数重置代码无效的原因。
1. 为什么你的分数重置代码没生效?
你写的这行代码:
if($currentQuestion==1){ $_SESSION['score'] == 0; }
有两个关键问题:
- 用了**比较运算符
==**而不是赋值运算符=,这行代码只是在判断$_SESSION['score']是否等于0,根本没有修改分数的值,改成$_SESSION['score'] = 0;才是正确的赋值逻辑。 - 触发条件不匹配:当用户刷新页面时,
$_POST["currentQuestion"]不存在,你的代码会把$currentQuestion初始化为0(也就是第一题),而不是1,所以这个if判断根本不会执行。
2. 核心漏洞的修复方案:用Session跟踪当前题目
问题根源在于你只靠POST参数传递当前题目,刷新页面时POST数据丢失,就会回到第一题,但Session里的分数没被重置。正确的做法是用Session来维护当前题目位置,这样刷新页面时会保留当前进度,而不是跳回第一题;如果需要重置测验,再专门处理。
修改后的核心代码片段
<?php session_start(); // 初始化Session中的测验状态:当前题目、分数 if (!isset($_SESSION['currentQuestion']) || !isset($_SESSION['score'])) { $_SESSION['currentQuestion'] = 0; $_SESSION['score'] = 0; } $currentQuestion = $_SESSION['currentQuestion']; $score = $_SESSION['score']; $questionsAndAnswers = array( array("question" => "What early cartoon character created by the Disney Studio was Mickey Mouse based off of ?", "answer" => "Oswald The Lucky Rabbit"), // 其他题目数组... ); // 处理用户答题提交 if(isset($_POST["guess"])){ $userGuess = trim($_POST["guess"]); $correctAnswer = $questionsAndAnswers[$currentQuestion]["answer"]; // 最后一题处理(动态判断,新增/删除题目无需改代码) if($currentQuestion == count($questionsAndAnswers)-1){ session_destroy(); header("Location: http://students.purchase.edu/martin.mcnicholas/scriptingfortheweb/loginmain.html"); exit(); } // 答对逻辑 if(strcasecmp($userGuess, $correctAnswer) === 0){ // 不区分大小写,提升用户体验 $_SESSION['score'] += 10; $_SESSION['currentQuestion']++; $currentQuestion = $_SESSION['currentQuestion']; echo "<span class='Stylize2'>"; echo "Your answer: $userGuess <br>"; echo "The answer expected: $correctAnswer<br>"; echo "Answer Correct!<br><br>"; // 图片展示逻辑 $images = [ 1 => 'MickeyMouse.png', 2 => 'Philo.jpg', 3 => 'warner.jpg', 4 => 'superman.jpg',5 => 'own.jpg',6 => 'scooby.png', 7 => 'garfield.jpg',8 => 'pok1.jpg',9 => 'peanuts.jpg', 10 => 'sam.jpg',11 => 'haim.jpg',12 => 'back.jpg', 13 => 'joe.jpg',14 => 'r.png',15 => 'wild.jpg', ]; if(isset($images[$currentQuestion])){ echo "<img src='{$images[$currentQuestion]}' alt='Question Image' height='200'><br><br>"; } else { echo "Image not found<br><br>"; } echo $_SESSION['score'] . " points<br>"; echo "Next Question Below<br></span><br><br>"; } // 答错逻辑 else { $_SESSION['score'] -= 5; $_SESSION['currentQuestion'] = 0; // 答错回到第一题 $currentQuestion = $_SESSION['currentQuestion']; echo "<span class='Stylize'>"; echo "Your answer: $userGuess <br>"; echo "You have failed..<br>"; echo '<img src="angry.gif" height="200"><br><br>'; echo $_SESSION['score'] . " points<br><br>"; echo "</span>"; // 音频播放 $audioFile = '251993__kwahmah-02__distorted-voice-18.wav'; echo "<audio autoplay loop>"; echo "<source src='$audioFile' type='audio/wav'>"; echo 'Your browser does not support the audio element'; echo "</audio>"; } } // 显示当前题目表单 echo "<form method='post'>"; echo "<h3>" . $questionsAndAnswers[$currentQuestion]["question"] . "</h3>"; echo "<input type='text' name='guess' required>"; echo "<button type='submit'>Submit Answer</button>"; echo "</form>"; ?>
3. 额外的代码优化建议
- 移除无效代码:你原来代码里的
$_SESSION["count"];是无效语句,直接删掉。 - 修正拼写错误:把
$questionsAndAnwsers改成$questionsAndAnswers,避免后续维护混淆。 - 变量命名更清晰:把
$guess改成$userGuess,一眼就能看出变量含义。 - 动态判断最后一题:用
count($questionsAndAnswers)-1代替硬编码的15,新增/删除题目时无需修改逻辑代码。 - 简化表单:不需要传递
currentQuestion参数,因为Session已经维护了当前进度,表单只需要提交用户答案即可。 - 增加容错性:用
trim()处理用户输入,避免空格导致的误判;用strcasecmp()实现不区分大小写的答案比较,提升用户体验。
4. 如果希望刷新页面重置整个测验
如果你想要用户刷新页面时直接重置测验(回到第一题+分数清零),可以在代码开头session_start();之后加上:
if ($_SERVER['REQUEST_METHOD'] === 'GET') { // 非表单提交的GET请求(刷新页面),重置测验 session_destroy(); session_start(); $_SESSION['currentQuestion'] = 0; $_SESSION['score'] = 0; }
内容的提问来源于stack exchange,提问作者user9453652
相关产品推荐
相关产品推荐

