首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >API调用问题

API调用问题
EN

Stack Overflow用户
提问于 2022-09-16 00:49:57
回答 2查看 68关注 0票数 0

我正在创建一个使用开放琐事DB和PHP的问答网络应用程序。我现在的问题是检查用户选择的选项是否正确。我意识到这个程序正在进行另一个API调用,每次都会得到一组完全不同的问题,所以使用所选选项检查的选项完全不同。我是否可以存储API的第一个结果,然后用它检查所选的结果,而不是每次都进行新的调用?

这是我的控制器

代码语言:javascript
复制
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"; // I used this line to find out that the problem.
                    }
                    
                 }
  
                    }
        else
        {
        $this->view('quiz', $data);
        }
    }

这是我的观点

代码语言:javascript
复制
<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">
                 <?
                 foreach ($data as $key => $value):
                    foreach ($value as $key => $k):?>
                         <div class="tab">
                             <span><p><? echo $key+1  ?></p></span>
                             <h4 class="card-title"> <? echo $k["question"] .  "<br>";?></h4>
                                 <? 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="<? echo $key ?>" value="<? echo " $incorrect"; ?>"> <? echo " $incorrect"; ?>
    
</div>
                    <?endforeach ?>
                   <input type="radio" class="form-check-input" id="rad2" name="<? echo "$key" ?>" value="<? echo $k["correct_answer"]; ?>"> <? 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> 
         
    <?endforeach ?>
 <?endforeach ?>
</div>

我能得到的任何帮助都将不胜感激。提前谢谢。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-09-16 01:30:26

好的,您正在执行一个API请求,呈现一个带有问题的页面,然后当用户提交答案时,要重用来自原始API的结果,确认答案是正确的吗?

由于api不允许您使用请求哈希或问题ID检索相同的问题,因此需要在代码中引入一个层,该层存储来自API请求的信息,以便在下一个请求中使用。

查看您的编码级别,最简单的解决方案是开始使用$_SESSION全局存储将问题数组存储到会话中,然后当用户提交他们的答案时检查这个会话信息。

虽然我认为您应该有足够的时间来查看文档并进一步发展,但是让我们把这一点讲一下:

代码语言:javascript
复制
        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);
    $_SESSION['quizQuestions'] = $result;
    return $result;
}

public function quiz()
{
    if($_SERVER["REQUEST_METHOD"]=="POST" && isset($_SESSION['quizQuestions']))
    {
        $sum = 0;
        foreach ($_SESSION['quizQuestions'] 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"; // I used this line to find out that the problem.
            }

        }
        $_SESSION['quizQuestions'] = null;
        // render view..
    }
    else
    {
        $get_data= $this->callAPI('GET', 'https://opentdb.com/api.php?amount=10&category=18', false);
        $data = json_decode($get_data, true);
        $this->view('quiz', $data);
    }
}

这显然需要更多的工作,但我希望你明白要点。还请注意,$_POST[key]键中的修复将被视为常量,而不是变量。

票数 1
EN

Stack Overflow用户

发布于 2022-09-16 03:13:35

你的问题不够清晰。我想它应该说

我做了一个API请求来获取问题和答案。我创建了一个带有<form>的HTML页面来问问题。然后,表单向脚本发出post请求,在那里我检查答案。当玩家提交答案时,我需要存储要使用的答案。

根据链接中的API文档,您只能执行GET请求。

因此,post字段不适用。

代码语言:javascript
复制
$request = array();
$request[] = "Accept: application/json";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $request);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);    
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);   
curl_setopt($ch, CURLOPT_URL, 'https://opentdb.com/api.php?amount=10&category=21&difficulty=easy&type=multiple'); 
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_TIMEOUT,10);
curl_setopt($ch, CURLOPT_FAILONERROR,true);
curl_setopt($ch, CURLOPT_POST, false);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_ENCODING,"");
curl_setopt($ch, CURLOPT_VERBOSE, true);

$response = json_decode(curl_exec($ch),true);
var_export($response);

上面的内容返回如下:

代码语言:javascript
复制
    array (
  'response_code' => 0,
  'results' => 
  array (
    0 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'In golf, what name is given to a hole score of two under par?',
      'correct_answer' => 'Eagle',
      'incorrect_answers' => 
      array (
        0 => 'Birdie',
        1 => 'Bogey',
        2 => 'Albatross',
      ),
    ),
    1 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'How many soccer players should be on the field at the same time?',
      'correct_answer' => '22',
      'incorrect_answers' => 
      array (
        0 => '20',
        1 => '24',
        2 => '26',
      ),
    ),
    2 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Who won the 2015 Formula 1 World Championship?',
      'correct_answer' => 'Lewis Hamilton',
      'incorrect_answers' => 
      array (
        0 => 'Nico Rosberg',
        1 => 'Sebastian Vettel',
        2 => 'Jenson Button',
      ),
    ),
    3 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'When was the first official international game played?',
      'correct_answer' => '1872',
      'incorrect_answers' => 
      array (
        0 => '1880',
        1 => '1863',
        2 => '1865',
      ),
    ),
    4 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Which boxer was banned for taking a bite out of Evander Holyfield\'s ear in 1997?',
      'correct_answer' => 'Mike Tyson',
      'incorrect_answers' => 
      array (
        0 => 'Roy Jones Jr.',
        1 => 'Evander Holyfield',
        2 => 'Lennox Lewis',
      ),
    ),
    5 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Which African American is in part responsible for integrating Major League baseball?',
      'correct_answer' => 'Jackie Robinson',
      'incorrect_answers' => 
      array (
        0 => 'Curt Flood',
        1 => 'Roy Campanella',
        2 => 'Satchell Paige',
      ),
    ),
    6 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Who won the premier league title in the 2015-2016 season following a fairy tale run?',
      'correct_answer' => 'Leicester City',
      'incorrect_answers' => 
      array (
        0 => 'Tottenham Hotspur',
        1 => 'Watford',
        2 => 'Stoke City',
      ),
    ),
    7 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Who did Steven Gerrard win the Champions League with?',
      'correct_answer' => 'Liverpool',
      'incorrect_answers' => 
      array (
        0 => 'Real Madrid',
        1 => 'Chelsea',
        2 => 'Man City',
      ),
    ),
    8 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'Which country will host the 2022 FIFA World Cup?',
      'correct_answer' => 'Qatar',
      'incorrect_answers' => 
      array (
        0 => 'USA',
        1 => 'Japan',
        2 => 'Switzerland',
      ),
    ),
    9 => 
    array (
      'category' => 'Sports',
      'type' => 'multiple',
      'difficulty' => 'easy',
      'question' => 'In the 2014 FIFA World Cup, what was the final score in the match Brazil - Germany?',
      'correct_answer' => '1-7',
      'incorrect_answers' => 
      array (
        0 => '1-5',
        1 => '1-6',
        2 => '2-6',
      ),
    ),
  ),
)

我不明白这点:

$_SERVER["REQUEST_METHOD"]是多余的。

还不清楚这是球员发帖的答案。

如果没有post,脚本就不会运行。

如果您使用的是$_SERVER["REQUEST_METHOD"],就好像您的curl请求将设置$_SERVER["REQUEST_METHOD"]的值一样,它不会。

这是错误的。

代码语言:javascript
复制
curl_setopt($curl, CURLOPT_HTTPHEADER, array(
      'APIKEY:xxxxxx',
      'Content-Type: application/json',
   ));

除非链接中有更多的文档,否则Content-Type: application/json是不正确的。

API文档说的是

使用此API不需要API密钥,只需生成下面的URL,在您自己的应用程序中使用它来检索琐事问题。

而且我没有发现任何文档表明请求应该是JSON。

我唯一能找到的请求格式是:

代码语言:javascript
复制
https://opentdb.com/api.php?amount=10&category=21&difficulty=medium&type=multiple

这不是POST请求、JSON请求或PUT请求。

这是GET请求。

解压缩结果嵌套数组的方式是有问题的。

这是错误的。

代码语言:javascript
复制
 foreach ($data as $key => $value){
   foreach ($value as $key => $k){

它可能应该像这样($key只使用一次)

代码语言:javascript
复制
 foreach ($data as $value){
   foreach ($value as $key => $k){

不过,第一个预见应该是这样的:

代码语言:javascript
复制
foreach($data['results'] as $key => list(,,,$question,$correctAnswer,$incorrectAnswers){
  $data[$key]['question'] = $question; 
  $data[$key]['correctAnswer'] = $correctAnswer; 
  $data[$key]['incorrectAnserers'] = $incorrectAnswers; 

}您应该有一个玩家id,用他们的id保存问题和答案。

我经常使用他们的ip地址作为用户id。

代码语言:javascript
复制
$id= intval(str_replace('.','',$_SERVER['REMOTE_ADDR']));

$jsn = json_encode($data,true);
file_put_contents("$id.jsn",$jsn);

然后为这些问题制作HTML表单。

您确实应该为玩家输入答案的表单提供HTML。因此,我将使用一个非常简化的形式。然后,将$form放到问题HTML中。

代码语言:javascript
复制
$form = '';
$form ."<form action="#" method="post>";
foreach($data as $number =>  list($question,$correctAnswer,$choices){
   $choices[] = $correctAnswer;
   shuffle($choices);
   $form .= "Q$number: $question<br>\n";
   $form .= "<input type=\"radio\" name=\"a$number\"  /> $choice[0]<br>\n";
   $form .= "<input type=\"radio\" name=\"a$number\"  /> $choice[1]<br>\n";       
   $form .= "<input type=\"radio\" name=\"a$number\"  /> $choice[2]<br>\n";       
   $form .= "<input type=\"radio\" name=\"a$number\"  /> $choice[3]<br>\n";
}
$form .= "<input type=\"hidden\" name=\"id\" value="$id\"\n";
$form .= "</form><br>\n";

然后,当答案被提交时,再次得到问题和答案。

代码语言:javascript
复制
$id = intval($_POST['id']);
$data = json_decode(file_get_contents("$is.jsn"),true);
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73738757

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档