首页 > 解决方案 > API调用失败时如何让PHP执行API调用

问题描述

我正在尝试编写 PHP 代码,从 Torah(创世纪、出埃及记、利未记、数字、申命记)中随机获取一段经文并显示该经文。如果它随机选择一个不存在的诗句,我会收到 JSON 数据“错误:”“$book 在 $chapter 结束。”

但是,当我包含下面的 while 循环时,代码似乎完全忽略了它。我可以从我的代码的另一部分看到它选择了一个不存在的诗句,但没有改变它。有没有办法在 PHP 中呈现以下逻辑?

而 $data 包含字符串 'ends at' -> 将书籍、章节、诗句设置为随机 -> 进行 api 调用并分配给变量 $data

while (strpos($data, 'ends at')) {

$bookNum = rand(1,5);

if ($bookNum == 1) {
    $book = 'Genesis';
}
elseif ($bookNum == 2) {
    $book = 'Exodus';
}
elseif ($bookNum == 3) {
    $book = 'Leviticus';
}
elseif ($bookNum == 4) {
    $book = 'Numbers';
}
elseif ($bookNum == 5) {
    $book = 'Deuteronomy';
}

$chapter = rand(1,50);

$chapter = strval($chapter);

$verse = rand(1,89);

curl_setopt($ch, CURLOPT_URL, "http://www.sefaria.org/api/texts/${book}.${chapter}.$verse");

$data = curl_exec($ch);

}

编辑:实际上似乎代码正在选择一个不存在的诗句,选择另一个不存在的诗句,然后停止。

例如,请参阅以下内容:

{“错误”:“出埃及记在第 40 章结束。”}创世记 18:37

标签: php

解决方案


According to the entry on curl_exec in the PHP Docs the function returns a boolean value unless called with a specific option:

Returns TRUE on success or FALSE on failure. However, if the CURLOPT_RETURNTRANSFER option is set, it will return the result on success, FALSE on failure.

Have you set the CURLOPT_RETURNTRANSFER option?


edit
Just saw your edit – the second one doesn't look like an error though, does it? It looks more like your server is not giving you the content of the chapter but only its title – or you might be accessing the wrong part of the JSON response?

Be it as it may, might I suggest a slight change of approach? I'd personally get rid of the while loop. Pick a book at random and stick with it, make your first call to a random chapter. If it exists (no error in the response data) – hey presto. If it doesn't, use the number returned (let's call it $maxChapters) in the error message to pick a new chapter at random: Exodus ends at chapter 40, so $maxChapters = 40; so $chapter = rand(1, $maxChapters); will guarantee a hit. That way you'll get a valid chapter in no more than two calls to your server. A simple regex can extract you $maxChapters from the error message.

Simplified, the code might look like this:


$bookNames = [
 1 => 'Genesis',
 2 => 'Exodus',
 3 => 'Leviticus',
 4 => 'Numbers',
 5 => 'Deuteronomy',
];

$bookNum = rand(1,5);
$book = $bookNames[$bookNum];
$chapter = rand(1,50);
$chapter = strval($chapter);

$verse = rand(1,89);

curl_setopt($ch, CURLOPT_URL, "http://www.sefaria.org/api/texts/${book}.${chapter}.$verse");

$data = curl_exec($ch);
$parsedData = json_parse($data)

if (isset($data->error) && strpos($data->error, 'ends at')) {
  preg_match(/.* ends at .* ([0-9]*)/, $data['error'], $parsedError);
  $maxChapters = $parsedError[1];
  $chapter = rand(1, $maxChapters);
  // --> initiate new request which will have a valid result this time
} else {
  // here's a valid result
  return $data;
}

edit 2
So I took another look at the API you're using, and the last part of your query (the verse) does not seem to do anything, so you may as well leave it out? You get the text content of your chapter using $chapter = $parsedData->text, which will in turn be an array of verses. You could then do


while (!isset($chapter[$verse]) {
  $verse = $verse = rand(1,89);
}
$result = $chapter[$verse];

推荐阅读