【问题标题】:PHP waiting for response to change statusPHP等待响应更改状态
【发布时间】:2020-02-25 01:12:15
【问题描述】:

我正在尝试实现 SkyScanner API...

我需要打电话:

"http://partners.api.skyscanner.net/apiservices/pricing/uk1/v1.0/
    {SessionKey}?apiKey={apiKey}
    &pageIndex=0
    &pageSize=10"

所以我写:

$res1 = $client1->get('http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/'.$session_id.'?apikey=APIKEY&pageIndex=0&pageSize=10"');

 $res1 = json_decode($res1->getBody()->getContents(), true);
$res1 = collect($res1);

我需要等待响应才能将状态从UpdatePending 更改为UpdateCompleted

API 文档:

继续请求第 0 页,直到获得带有 pageIndex=0 的 UpdatesComplete 以半秒到一秒的间隔。一旦你得到 UpdatesComplete 您可以要求任何页面和页面大小。

当状态为 UPDATESPENDING 时,您应该只请求第 0 页 因为每个页面的内容可能会在更新之前发生变化 已完成。

如何等待响应改变状态...

我试试:

while ($res1['Status'] == 'UpdatesPending') {
    echo 'waiting';
}

dd($res1);

但没有尽头……

如何等待响应改变状态?

【问题讨论】:

  • 你需要一个 do/while 循环。在循环内请求状态(代码的前 3 行),然后在状态更改时中断它。确保为其添加睡眠,否则您将在他们的服务器上发送垃圾邮件,直到它发生变化。
  • @aynber 请写为答案

标签: php laravel api guzzle skyscanner


【解决方案1】:

你可以在你的代码之前回显'waiting' 那么在另一行是完整的 echo completed

echo 'waiting...';
$res1 = $client1->get('http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/'.$session_id.'?apikey=APIKEY&pageIndex=0&pageSize=10"');

$res1 = json_decode($res1->getBody()->getContents(), true);
$res1 = collect($res1);
echo 'completed';

【讨论】:

  • 不,这不是我想要的!我需要调用 API 并等待 res1 更改状态 - $res1->STatus ...
【解决方案2】:

您需要创建一个 do/while 循环来检查状态并在状态更改时退出它:

do{

    $res1 = $client1->get('http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/'.$session_id.'?apikey=APIKEY&pageIndex=0&pageSize=10"');

    $res1 = json_decode($res1->getBody()->getContents(), true);
    $res1 = collect($res1);
    if($res1['Status'] == 'UpdatesPending') echo "waiting...<br />\n";
    sleep(5); // Make it sleep 5 seconds so as to not spam the server
while($res1['Status'] == 'UpdatesPending');

echo "Done!";

请注意,在整个过程完成之前,您不会得到任何实际反馈。

【讨论】:

【解决方案3】:

如果你使用guzzle作为PHP HTTP Client,那么你只需要定义重试决定器和重试计时器

public function retryDecider() 
{
  return function ($retries, Request $request, Response $response = null, RequestException $exception = null) 
  {
    // maximum retries is three times
    if ($retries >= 3) {
      return false; 
    }

    if ($response) {
      $content = $response->getBody()->getContents();
      $res1 = json_decode($content, true);
      $res1 = collect($res1);

      // maybe you need to change this one to 'substr' or regex or something else
      if ($res1['Status'] == 'UpdatesComplete') {
        return false;
      }

    }

    return true; // we will request again
  };
}

public function retryDelay()
{
    return function ($numberOfRetries) {
        return 1000; // 1 second
    };
}

并使用该决策器和延迟功能

$handlerStack = HandlerStack::create(new CurlHandler());
$handlerStack->push(Middleware::retry($this->retryDecider(), $this->retryDelay()));
$client = new Client(array('handler' => $handlerStack));

并得到您的回复

$url = 'http://partners.api.skyscanner.net/apiservices/pricing/uk2/v1.0/'.$session_id.'?apikey=APIKEY&pageIndex=0&pageSize=10"';
$response = $client->request('GET', $url)->getBody()->getContents();

你可以解码最后一个$response 来决定你想要做什么。

通过这种方法,您可以决定哪个响应是有效的,并根据需要重试请求。

【讨论】:

    猜你喜欢
    • 2022-01-06
    • 1970-01-01
    • 2022-07-15
    • 1970-01-01
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2018-07-18
    • 2020-12-28
    相关资源
    最近更新 更多