我有这个URL,我可以从Outlook获取事件:
// ! API sorting by Id doesn't work so we'll have to implement it ourselves.
$url = 'https://outlook.office365.com/api/v2.0/users/' . $this->user . '/CalendarView/'
. '?startDateTime=' . $start_datetime
. '&endDateTime=' . $end_datetime
.'&$top=100';
我对此很陌生,现在我正在努力得到如下答案:
$http = new \Http_Curl();
$http->set_headers( $this->get_headers() );
$response = $http->get( $url );
where I have this `HTTP_CURL` class that contains methods as below:
public function get( $url ) {
return $this->request( $url, 'GET', $this->headers );
}
private function request( $url, $method, $headers, $data = false ) {
$handle = curl_init();
curl_setopt( $handle, CURLOPT_URL, $url );
curl_setopt( $handle, CURLOPT_SSL_VERIFYPEER, false );
curl_setopt( $handle, CURLOPT_RETURNTRANSFER, true );
if ( $this->headers )
curl_setopt( $handle, CURLOPT_HTTPHEADER, $this->headers );
curl_setopt( $handle, CURLOPT_VERBOSE, true );
curl_setopt( $handle, CURLINFO_HEADER_OUT, true );
switch ( $method ) {
case 'POST':
curl_setopt( $handle, CURLOPT_POST, true );
curl_setopt( $handle, CURLOPT_POSTFIELDS, $data );
break;
case 'PATCH':
curl_setopt( $handle, CURLOPT_POSTFIELDS, $data );
curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, 'PATCH' );
break;
case 'DELETE':
curl_setopt( $handle, CURLOPT_CUSTOMREQUEST, 'DELETE' );
break;
}
$http_response = curl_exec( $handle );
curl_close( $handle );
return json_decode( $http_response );
}
我需要的是在响应中获取HTTP错误代码。 根据Outlook HTTP 429 Too Many Requests响应状态代码表示用户在给定的时间内发送了太多请求("速率限制")。此响应中可能包含Retry-After标头,指示在发出新请求之前需要等待多长时间。
那么如何获取此HTTP错误代码和Retry-After?喜欢这个链接:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429
我尝试过这一行:$httpcode = curl_error($url, CURLINFO_HTTP_CODE);
我一直都是空的。
答案 0 :(得分:1)
您在curl_error功能中使用了无效参数。应该是curl_error($handle)
。
最好的方法是使用Guzzle PHP HTTP客户端。它有methods for getting response headers。您可以使用this perfect example发出重复请求:
<?php require './vendor/autoload.php'; use GuzzleHttp\Client; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Exception\RequestException; use GuzzleHttp\Handler\CurlHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Middleware; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; class TestRetry { public function test() { $handlerStack = HandlerStack::create(new CurlHandler()); $handlerStack->push(Middleware::retry($this->retryDecider(), $this->retryDelay())); $client = new Client(array('handler' => $handlerStack)); $response = $client->request( 'GET', // @todo replace to a real url!!! 'https://500-error-code-url' )->getBody()->getContents(); return \GuzzleHttp\json_decode($response, true); } public function retryDecider() { return function ( $retries, Request $request, Response $response = null, RequestException $exception = null ) { // Limit the number of retries to 5 if ($retries >= 5) { return false; } // Retry connection exceptions if ($exception instanceof ConnectException) { return true; } if ($response) { // Retry on server errors if ($response->getStatusCode() >= 500 ) { return true; } } return false; }; } /** * delay 1s 2s 3s 4s 5s * * @return Closure */ public function retryDelay() { return function ($numberOfRetries) { return 1000 * $numberOfRetries; }; } } $TestRetry = new TestRetry(); $TestRetry->test();
我为您的案例略微更改了此代码:
<?php
require './vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Handler\CurlHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
class MyOutlookApiClient {
const BASE_API_URL = 'https://outlook.office365.com/api/v2.0';
public $user;
protected $retryOnErrors;
protected $retryMaxCount;
/**
* @param $user
*/
public function __construct($user)
{
$this->user = $user;
}
/**
* @param array $retryOnErrors
* @return $this
*/
public function setRetryOnErrors($retryOnErrors=[])
{
$this->retryOnErrors = $retryOnErrors;
return $this;
}
/**
* @param $retryMaxCount
* @return $this
*/
public function setRetryMaxCount($retryMaxCount = 5)
{
$this->retryMaxCount = $retryMaxCount;
return $this;
}
/**
* @param $startDatetime
* @param $endDatetime
* @param $top
* @return mixed
*/
public function getUsersCalendarView($startDatetime, $endDatetime, $top)
{
$handlerStack = HandlerStack::create(new CurlHandler());
$handlerStack->push(Middleware::retry($this->retryDecider(),
$this->retryDelay()));
$client = new Client(array('handler' => $handlerStack));
$calendarViewUrl = self::BASE_API_URL.'/users/'.$this->user.'/CalendarView/';
$queryParams = [
'startDateTime' => $startDatetime,
'endDateTime' => $endDatetime,
'top' => $top
];
$response = $client
->request('GET', $calendarViewUrl, ['query' => $queryParams])
->getBody()
->getContents();
return \GuzzleHttp\json_decode($response, true);
}
/**
* @return Closure
*/
public function retryDecider()
{
return function (
$retries,
Request $request,
Response $response = null,
RequestException $exception = null
) {
// Limit the number of retries to 5
if ($retries >= $this->retryMaxCount) {
return false;
}
// Retry connection exceptions
if ($exception instanceof ConnectException) {
return true;
}
if ($response) {
// Retry on server errors
$responseCode = $response->getStatusCode();
if (
($this->retryOnErrors && in_array($responseCode, $this->retryOnErrors))
|| ($responseCode >= 500)
) {
return true;
}
}
return false;
};
}
/**
* delay 1s 2s 3s 4s 5s
*
* @return Closure
*/
public function retryDelay()
{
return function ($numberOfRetries) {
return 1000 * $numberOfRetries;
};
}
}
// your code to init variables here
// ...
$myOutlookApiClient = new MyOutlookApiClient($user);
$myOutlookApiClient
->setRetryOnErrors([429])
->setRetryMaxCount(5)
->getUsersCalendarView($startDatetime, $endDatetime, $top);