获取cURL响应头和响应体

4
我正在使用Imgur API上传图片。他们在API文档中详细说明了每个请求(当我通过他们的API上传图片时)都有响应头,这将告诉我帐户还剩多少信用额度。
我需要返回HTTP响应头X-RateLimit-ClientRemaining。这是我目前用来获取cURL主体的代码:
$filename = dirname(realpath(__FILE__))."/images/$value";
$client_id = "f*************c";
$handle = fopen($filename, "r");
$data = fread($handle, filesize($filename));
$pvars   = array('image' => base64_encode($data));
$timeout = 30;
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://api.imgur.com/3/image.json');
curl_setopt($curl, CURLOPT_TIMEOUT, $timeout);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization: Client-ID ' . $client_id));
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $pvars);
$out = curl_exec($curl);
curl_close ($curl);
$pms = json_decode($out,true);
$url=$pms['data']['link'];
if($url!=""){
    // add to success
    array_push($success, $url);
}
else {
    // add to fail
    $p = $value.' failed, error: '.$pms['data']['error'];
    array_push($fail, $p);
}

($value 是来自一个我没有包含的循环)


Note: 请注意,这是一条关于IT技术的翻译内容。

see my example below. - jpaljasma
1个回答

5
为什么不尝试一下呢?
curl_setopt($curl, CURLOPT_HEADER, 1);

要同时接收头信息和内容,你只需要从$out变量中解析出头信息即可。

以下是从Google获取时的完整工作示例:

<?php

error_reporting(E_ALL);
ini_set('display_errors', 'On');
header('Content-Type: text/plain; charset=utf-8');

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'https://www.google.com/');
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_POST, 0);
curl_setopt($curl, CURLOPT_HEADER, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
$out = curl_exec($curl);
curl_close ($curl);

$out = preg_split('/(\r?\n){2}/', $out, 2);
$headers = $out[0];
$headersArray = preg_split('/\r?\n/', $headers);
$headersArray = array_map(function($h) {
    return preg_split('/:\s{1,}/', $h, 2);
}, $headersArray);

$tmp = [];
foreach($headersArray as $h) {
    $tmp[strtolower($h[0])] = isset($h[1]) ? $h[1] : $h[0];
}
$headersArray = $tmp; $tmp = null;
// $headersArray contains your headers
print_r($headersArray);
?>

这将产生以下结果:
Array
(
    [http/1.1 200 ok] => HTTP/1.1 200 OK
    [date] => Thu, 29 Oct 2015 13:26:39 GMT
    [expires] => -1
    [cache-control] => private, max-age=0
    [content-type] => text/html; charset=ISO-8859-1
    [p3p] => CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."
    [server] => gws
    [x-xss-protection] => 1; mode=block
    [x-frame-options] => SAMEORIGIN
    [set-cookie] => NID=72=lw6pIMe05MoXu3aykbPi0BR9gZomWqTXBwsk6VG7xtLbLLeWc0I__CLGydE-auttR0G8VulKoZOTrv4eAZovJJi9QyB5hgxBue9pLWcX794Iv6gPlM2QaL9I2t6tjtrADtczAZpHhbnLvjmeDn_AmRj0xKkFPrMhYR84C5lNgzgo1iJpzr5qG2y6xg; expires=Fri, 29-Apr-2016 13:26:39 GMT; path=/; domain=.google.com; HttpOnly
    [alternate-protocol] => 443:quic,p=1
    [alt-svc] => quic="www.google.com:443"; p="1"; ma=600,quic=":443"; p="1"; ma=600
    [accept-ranges] => none
    [vary] => Accept-Encoding
    [transfer-encoding] => chunked
)

根据您上面的示例,您需要使用$headersArray['x-ratelimit-clientremaining'];

希望这有所帮助。

编辑:这是一个快速的方法(因为您的响应不包含换行符):

$matches = null;
preg_match('/X-RateLimit-ClientRemaining:\s*(\d+)/i', $out, $matches);
echo sprintf('X-RateLimit-ClientRemaining: %u', $matches[1]);

产生:

X-RateLimit-ClientRemaining: 11850

无法工作。我可以看到返回的标题,但它们没有进入 $headersArray;只有一个元素:[1]=>string(1) "1"。 - James
您可能需要稍微修改功能以使其与您的代码配合使用 - 该示例适用于 www.google.com,但可能不适用于您的 API。您能把API的响应以文本形式发送给我吗?如果需要使用 gist... 我会调整解析函数。 - jpaljasma
API响应中的换行符都去哪了?难怪解析起来这么困难... - jpaljasma
谁知道呢。我只是在使用你的代码,对于这个API的使用并不熟悉,所以我只是在胡乱尝试。不过还是谢谢你的帮助 :) - James
$matches是从哪里来的? - James
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接