Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get cURL response headers as well as response body

I'm using the Imgur API to upload images. They have detailed in their API docs that each request (when I upload an image via their API) also has response headers, which will tell me how much credit the account has left.

I need to return the HTTP response header X-RateLimit-ClientRemaining. Here is the code I am currently using to get the cURL body back:

$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 is coming from a loop I have not included)

like image 507
James Avatar asked Nov 05 '25 00:11

James


1 Answers

Why not try

curl_setopt($curl, CURLOPT_HEADER, 1);

To receive both headers and content. All you need to do is parse headers from the $out variable.

Here's fully working example while fetching from 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);
?>

This produces:

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
)

From your example above, you'd seek $headersArray['x-ratelimit-clientremaining'];

Hope that helps.

Edit: here's the quick way (because your response does not contain linefeeds):

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

Produces:

X-RateLimit-ClientRemaining: 11850
like image 189
jpaljasma Avatar answered Nov 06 '25 13:11

jpaljasma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!