如何用foreach和数组将PHP测验转换为HTML表单测验?
问题分析与解决方案
两种方法的核心问题
方法1(单表单逐题切换)的问题
- 没通过状态(比如Session)记录答题进度,每次提交后循环都从第一个元素开始,
break直接终止循环,根本没法切换到下一题。 - 错误执行
$countries[] = $input;,把用户输入追加到原数组,打乱了原本的首都-国家键值对结构。 - 输入框里的
<?php $input; ?>没加echo,用户输入的内容不会显示在输入框里。 - 没保存已答对的题目数,每次刷新都会重置数据。
方法2(多问题独立校验)的问题
- 所有输入框的
name都是input,提交后只能拿到最后一个输入框的值,无法区分是哪个问题的答案。 - 所有提交按钮都属于同一个表单,点击任意按钮都会提交整个表单,没法单独校验当前问题。
- 同样存在修改
$countries数组和输入框未输出值的问题。
方案1:单表单逐题切换(符合你的方法1期望)
用Session记录当前答题的索引,每次提交后判断答案对错,然后切换到下一题,直到所有题目完成。
<?php session_start(); // 初始化题目数组(修正拼写错误:Zouth-Korea → South-Korea) $countries = [ 'Tokyo' => 'Japan', 'Mexico-city' => 'Mexico', 'Washington D.C.' => 'USA', 'New Delhi' => 'India', 'Seoul' => 'South-Korea', 'Peking' => 'China', 'Abuja' => 'Nigeria', 'Buenos Aires' => 'Argentina', 'Cairo' => 'Egypt', 'London' => 'England', ]; // 初始化Session变量 if (!isset($_SESSION['current_index'])) { $_SESSION['current_index'] = 0; } if (!isset($_SESSION['correct_count'])) { $_SESSION['correct_count'] = 0; } $feedback = ''; $current_country = ''; $current_capital = ''; $user_input = ''; // 获取当前题目的键值对 $cities = array_keys($countries); $countries_list = array_values($countries); if ($_SESSION['current_index'] < count($countries)) { $current_capital = $cities[$_SESSION['current_index']]; $current_country = $countries_list[$_SESSION['current_index']]; } // 处理表单提交 if (isset($_POST['submit'])) { $user_input = trim($_POST['input']); // 大小写不敏感判断答案对错 if (strcasecmp($user_input, $current_capital) === 0) { $feedback = '<span style="color: green;">Correct!</span>'; $_SESSION['correct_count']++; } else { $feedback = "<span style='color: red;'>Incorrect, {$user_input} is not the capital of {$current_country}. The correct answer is: {$current_capital}</span>"; } // 切换到下一题,超出范围则重置(可选) $_SESSION['current_index']++; if ($_SESSION['current_index'] >= count($countries)) { // 所有题目完成,显示结果 $final_result = "Quiz completed! You got {$_SESSION['correct_count']}/" . count($countries) . " correct."; // 重置Session,方便重新开始 session_destroy(); } } ?> <div class="pblock"> <?php if (isset($final_result)): ?> <h3><?php echo $final_result; ?></h3> <a href="<?php echo $_SERVER['PHP_SELF']; ?>">Restart Quiz</a> <?php else: ?> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post" id="quiz-form"> <p><?php echo "What is the capital city of {$current_country}?"; ?></p> <p> <input type="text" name="input" id="input" value="<?php echo htmlspecialchars($user_input); ?>" required /> </p> <?php if (!empty($feedback)): ?> <p><?php echo $feedback; ?></p> <?php endif; ?> <br> <input type="submit" name="submit" value="Check Answer" /> </form> <?php endif; ?> </div>
方案2:多问题独立校验(符合你的方法2期望)
每个问题用独立的小表单,给每个输入框和提交按钮设置唯一标识,提交后根据标识判断是哪个问题,然后给出反馈。
<?php // 初始化题目数组(修正拼写错误) $countries = [ 'Tokyo' => 'Japan', 'Mexico-city' => 'Mexico', 'Washington D.C.' => 'USA', 'New Delhi' => 'India', 'Seoul' => 'South-Korea', 'Peking' => 'China', 'Abuja' => 'Nigeria', 'Buenos Aires' => 'Argentina', 'Cairo' => 'Egypt', 'London' => 'England', ]; $feedback = []; // 处理表单提交 if (isset($_POST['submit'])) { $question_key = $_POST['question_key']; $user_input = trim($_POST['input_' . $question_key]); $correct_capital = $question_key; $country = $countries[$correct_capital]; // 大小写不敏感判断答案对错 if (strcasecmp($user_input, $correct_capital) === 0) { $feedback[$question_key] = "<span style='color: green;'>Correct!</span>"; } else { $feedback[$question_key] = "<span style='color: red;'>Incorrect, {$user_input} is not the capital of {$country}. The correct answer is: {$correct_capital}</span>"; } } ?> <div class="pblock"> <?php foreach ($countries as $capital => $country): ?> <div class="question-block"> <p>What is the capital city of <?php echo $country; ?>?</p> <form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post"> <input type="hidden" name="question_key" value="<?php echo htmlspecialchars($capital); ?>" /> <input type="text" name="input_<?php echo htmlspecialchars($capital); ?>" value="<?php echo isset($_POST['input_' . $capital]) ? htmlspecialchars($_POST['input_' . $capital]) : ''; ?>" required /> <input type="submit" name="submit" value="Check Answer" /> </form> <?php if (isset($feedback[$capital])): ?> <p><?php echo $feedback[$capital]; ?></p> <?php endif; ?> <br> </div> <?php endforeach; ?> </div>
关键改进点说明
- 状态管理:方案1用Session保存答题进度和正确数,避免每次刷新重置数据。
- 唯一标识:方案2给每个问题的输入框和隐藏域设置唯一键,确保能区分不同问题的提交。
- 避免修改原数组:不再执行破坏原数据的
$countries[] = $input;操作。 - 输入安全:用
htmlspecialchars()转义用户输入,防止XSS攻击。 - 用户体验优化:用
strcasecmp()做大小写不敏感判断,降低答题门槛。
内容的提问来源于stack exchange,提问作者Ro.
相关产品推荐
相关产品推荐

