You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测验应用开发:如何动态展示数量可变的答题选项?

看起来你已经搞定了从数据库拉取单题数据的核心部分,接下来咱们把逐题展示的逻辑补得更顺畅些,直接上代码示例和细节说明:

1. 完善单题展示的基础代码

先把你现有的代码补全,确保选项能正确循环输出(假设你的选项数据存在$question['options']数组里,每个元素包含选项文本和对应值):

<?php
// 这里替换成你从数据库获取单题数据的逻辑,比如:
// $question = fetchSingleQuestionFromDB(); // 你的自定义数据库查询函数
?>

<div class="question-container">
    <h3><?php echo htmlspecialchars($question["questionText"]); ?></h3>
    <div class="options-group">
        <?php foreach ($question['options'] as $option): ?>
            <label>
                <input type="radio" name="optradio" value="<?php echo htmlspecialchars($option['value']); ?>">
                <?php echo htmlspecialchars($option['text']); ?>
            </label>
            <br>
        <?php endforeach; ?>
    </div>
    <button type="button" id="next-btn">下一题</button>
</div>

⚠️ 重点提醒:一定要用htmlspecialchars()转义输出内容,防止XSS跨站脚本攻击,这是Web开发的基础安全规范。

2. 实现逐题切换的两种常用方案

如果你希望用户答完一题后自动加载下一题,这里提供两种实用方案:

方案A:PHP会话+页面刷新(简单无JS)

用PHP的$_SESSION记录当前答题进度,点击下一题时提交表单,后端自动切换题目:

<?php
session_start();
// 初始化当前题目ID,默认从1开始(假设你的题目ID是自增主键)
if (!isset($_SESSION['current_q_id'])) {
    $_SESSION['current_q_id'] = 1;
}

// 处理下一题提交请求
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['next_question'])) {
    // 先保存当前用户的答案(可以存到数据库或会话)
    $_SESSION['user_answers'][$_SESSION['current_q_id']] = $_POST['optradio'];
    
    // 切换到下一题
    $_SESSION['current_q_id']++;
    
    // 检查是否已到最后一题
    $total_q_count = getTotalQuestionCount(); // 你的自定义函数:获取数据库总题数
    if ($_SESSION['current_q_id'] > $total_q_count) {
        // 跳转到答题结果页面
        header('Location: result.php');
        exit;
    }
}

// 获取当前要展示的题目
$question = fetchQuestionById($_SESSION['current_q_id']);
?>

<form method="POST" action="index.php">
    <div class="question-container">
        <h3>第 <?php echo $_SESSION['current_q_id']; ?> 题</h3>
        <p><?php echo htmlspecialchars($question["questionText"]); ?></p>
        <div class="options-group">
            <?php foreach ($question['options'] as $option): ?>
                <label>
                    <input type="radio" name="optradio" value="<?php echo htmlspecialchars($option['value']); ?>" required>
                    <?php echo htmlspecialchars($option['text']); ?>
                </label>
                <br>
            <?php endforeach; ?>
        </div>
        <button type="submit" name="next_question">下一题</button>
    </div>
</form>

方案B:AJAX异步加载(无刷新体验更优)

如果不想让页面刷新,用JS+AJAX实现无缝切换题目,用户体验更好:

前端HTML+JS代码

<div class="question-container">
    <h3 id="q-number">第 1 题</h3>
    <p id="q-text"></p>
    <div id="options-group" class="options-group"></div>
    <button type="button" id="next-btn">下一题</button>
</div>

<script>
let currentQId = 1;
const totalQCount = <?php echo getTotalQuestionCount(); ?>;

// 加载初始题目
loadQuestion(currentQId);

document.getElementById('next-btn').addEventListener('click', function() {
    const selectedOption = document.querySelector('input[name="optradio"]:checked');
    if (!selectedOption) {
        alert('请先选择一个选项哦!');
        return;
    }
    
    // 异步保存当前答案
    saveAnswer(currentQId, selectedOption.value);
    
    // 切换下一题
    currentQId++;
    if (currentQId > totalQCount) {
        window.location.href = 'result.php';
        return;
    }
    loadQuestion(currentQId);
});

// 加载指定ID的题目
function loadQuestion(qId) {
    fetch(`get_question.php?id=${qId}`)
        .then(res => res.json())
        .then(data => {
            document.getElementById('q-number').textContent = `第 ${qId} 题`;
            document.getElementById('q-text').textContent = data.questionText;
            
            // 清空并重新渲染选项
            const optionsGroup = document.getElementById('options-group');
            optionsGroup.innerHTML = '';
            data.options.forEach(opt => {
                const label = document.createElement('label');
                label.innerHTML = `
                    <input type="radio" name="optradio" value="${opt.value}">
                    ${opt.text}
                `;
                optionsGroup.appendChild(label);
                optionsGroup.appendChild(document.createElement('br'));
            });
        })
        .catch(err => alert('题目加载失败,请重试'));
}

// 异步保存答案
function saveAnswer(qId, answer) {
    fetch('save_answer.php', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
        },
        body: `q_id=${qId}&answer=${answer}`
    });
}
</script>

后端辅助文件

get_question.php(返回题目JSON数据)

<?php
header('Content-Type: application/json');
$qId = $_GET['id'] ?? 1;
$question = fetchQuestionById($qId);

// 转义后输出JSON
echo json_encode([
    'questionText' => htmlspecialchars($question['questionText']),
    'options' => array_map(function($opt) {
        return [
            'value' => htmlspecialchars($opt['value']),
            'text' => htmlspecialchars($opt['text'])
        ];
    }, $question['options'])
]);
?>

save_answer.php(保存用户答案)

<?php
session_start();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $qId = $_POST['q_id'];
    $answer = $_POST['answer'];
    // 可以选择存到数据库,或者先存在会话中
    $_SESSION['user_answers'][$qId] = $answer;
    echo 'success';
}
?>
3. 额外注意事项
  • 答题结束后,记得清空会话中的current_q_id和user_answers数据,避免影响下次答题。
  • 对于AJAX方案,建议增加加载状态提示(比如按钮置灰+加载动画),提升用户体验。

内容的提问来源于stack exchange,提问作者Adnan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:00:46