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

使用Open trivia DB API与PHP开发测验应用的答案校验问题

问题

我正在使用Open Trivia DB API和PHP开发一款测验Web应用,当前遇到的问题是校验用户所选选项是否为正确答案时,程序每次提交请求都会重新调用API获取完全不同的题目集,导致用于校验的题目与用户作答的题目完全不符。请问如何存储首次API调用的结果,并用其来校验用户选项,而非每次重新调用API?

控制器代码

public function callAPI($method, $url, $data){
    $curl = curl_init();
    switch ($method){
      case "POST":
         curl_setopt($curl, CURLOPT_POST, 1);
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
         break;
      case "PUT":
         curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
         if ($data)
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);                              
         break;
      default:
         if ($data)
            $url = sprintf("%s?%s", $url, http_build_query($data));
   }
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'APIKEY:xxxxxx',
      'Content-Type: application/json',
   ));
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
   $result = curl_exec($curl);
   if(!$result){die("Connection Failure");}
   curl_close($curl);
   return $result;
}

public function quiz()
{
    $get_data= $this->callAPI('GET', 'https://opentdb.com/api.php?amount=10&category=18', false);
    $data = json_decode($get_data, true);
    if($_SERVER["REQUEST_METHOD"]=="POST")
    {
        $sum = 0;  
        foreach ($data as $key => $value)
        {
            foreach ($value as $key => $k)
            {
                if($_POST[$key]== $k['correct_answer'])
                {
                    $sum++;
                }
                
                echo"The question is ".$k['question']."you answered  $_POST[$key] and the correct answer is  ". $k['correct_answer']. " Your score is $sum"; // 用来排查问题的输出
            }
        }
    }
    else
    {
        $this->view('quiz', $data);
    }
}

视图代码

<div class="col-md-6 grid-margin stretch-card ">
    <form class="my-auto" id ="regForm" method="POST" action="">
        <div class="card">
            <div class="card-body">
                 <?php
                 foreach ($data as $key => $value):
                    foreach ($value as $key => $k):?>
                         <div class="tab">
                             <span><p><?php echo $key+1  ?></p></span>
                             <h4 class="card-title"> <?php echo $k["question"] .  "<br>";?></h4>
                                 <?php foreach ( $k["incorrect_answers"] as $incorrect):
                               ?>
        <div class="form-check">
            <label class="form-check-label" for="radio1"></label>
    <input type="radio" class="form-check-input" id="radio1" name="<?php echo $key ?>" value="<?php echo " $incorrect"; ?>"> <?php echo " $incorrect"; ?>
    
</div>
                    <?php endforeach ?>
                   <input type="radio" class="form-check-input" id="rad2" name="<?php echo "$key" ?>" value="<?php echo $k["correct_answer"]; ?>"> <?php echo  $k["correct_answer"]; ?> 
                   
                <div style="overflow:auto;">
                    <div style="float:right;">
                    <button type="button" class="btn btn-outline-danger btn-fw" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
                     <button type="button"class="btn btn-outline-primary btn-fw" id="nextBtn" onclick="nextPrev(1)">Next</button>
                    </div>
             </div>
         </div> 
         
    <?php endforeach ?>
 <?php endforeach ?>
</div>

解决方案

核心思路是将首次获取的题目数据存储到用户Session中,这样在POST提交校验时,直接从Session读取之前的题目,而非重新调用API。

步骤1:初始化Session

在控制器的quiz方法开头启动Session,确保Session可用:

public function quiz()
{
    session_start(); // 启动Session
    // 后续代码...
}

步骤2:修改题目获取与校验逻辑

只有当Session中没有存储题目时,才调用API获取新题目;校验时直接读取Session中的数据:

public function quiz()
{
    session_start();

    // 检查Session中是否已有题目数据
    if (!isset($_SESSION['quiz_questions'])) {
        $get_data= $this->callAPI('GET', 'https://opentdb.com/api.php?amount=10&category=18', false);
        $_SESSION['quiz_questions'] = json_decode($get_data, true);
    }
    $data = $_SESSION['quiz_questions']; // 从Session读取题目

    if($_SERVER["REQUEST_METHOD"]=="POST")
    {
        $sum = 0;  
        foreach ($data as $key => $value)
        {
            foreach ($value as $q_index => $question)
            {
                // 严格比对答案,同时处理可能的空格问题
                if(isset($_POST[$q_index]) && trim($_POST[$q_index]) === trim($question['correct_answer']))
                {
                    $sum++;
                }
                
                echo "题目:".$question['question']."<br>你的答案:".$_POST[$q_index]."<br>正确答案:".$question['correct_answer']."<br>当前得分:$sum<br><br>";
            }
        }
        // 校验完成后清空Session,避免重复使用同一套题目
        unset($_SESSION['quiz_questions']);
    }
    else
    {
        $this->view('quiz', $data);
    }
}

步骤3:视图代码优化

修正单选框的id唯一性问题,同时去掉选项输出时的多余空格,避免答案比对失败:

<!-- 修正错误选项的输出,去掉多余空格并设置唯一ID -->
<?php $incorrect_index = 0; ?>
<?php foreach ( $k["incorrect_answers"] as $incorrect): ?>
<div class="form-check">
    <label class="form-check-label" for="radio_<?php echo $key.'_'.$incorrect_index; ?>"></label>
    <input type="radio" class="form-check-input" id="radio_<?php echo $key.'_'.$incorrect_index; ?>" name="<?php echo $key ?>" value="<?php echo htmlspecialchars($incorrect); ?>"> <?php echo htmlspecialchars($incorrect); ?>
</div>
<?php $incorrect_index++; ?>
<?php endforeach ?>

<!-- 修正正确答案的输出,设置唯一ID -->
<input type="radio" class="form-check-input" id="rad2_<?php echo $key; ?>" name="<?php echo $key ?>" value="<?php echo htmlspecialchars($k["correct_answer"]); ?>"> <?php echo htmlspecialchars($k["correct_answer"]); ?>

关键注意点

  • Session依赖Cookie,需确保用户浏览器允许Cookie;
  • 校验完成后清空Session,避免用户刷新页面重复使用同一套题目;
  • 使用trim()处理答案前后空格,用===严格比对,避免匹配错误;
  • 用htmlspecialchars()转义题目和选项内容,防止XSS攻击。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 11:05:28