whispers whispers - 4 months ago 57
JSON Question

PHP + cURL, parsing header data

Summary:
I am using PHP/cURL to get some JSON data from Vimeo.

This has been working fine, (albeit their odd 'rate limit' requirements), using the following:

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $json_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array("authorization: Bearer ".$access_token)
));
$response = curl_exec($curl);
$response_info = curl_getinfo($curl);
$err = curl_error($curl);
curl_close($curl);


Which works fine when I covert to JSON and use the data output like so:

$vimeoJSON = json_decode($response, true);

echo '<h2 class="title">'.$vimeoJSON['name'] . '</h2>';


However, Vimeo sends back some needed data (current rate-limit and remaining limit..etc) in the HEADER RESPONSE...

So I searched around and read that you need to add this to the cURL options/params:

CURLOPT_HEADER => true,


So I did that:

$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $json_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HEADER => true,
CURLOPT_HTTPHEADER => array("authorization: Bearer ".$access_token)
));
$response = curl_exec($curl);
$response_info = curl_getinfo($curl);
$err = curl_error($curl);
curl_close($curl);


And used this to break up the information:

//get response header details
list($headers, $body) = explode("\n\n", $response, 2);
$headers = explode("\n", $headers);
foreach ($headers as $header) {
list($key, $value) = explode(':', $header, 2);
$headers[trim($key)] = trim($value);
}


And displayed it like so:

echo '<p>';
echo "Rate Limit: " . $headers['X-RateLimit-Limit'];
echo " / Remaining Limit: " . $headers['X-RateLimit-Remaining'] . '<br>';
echo "Reset Time: " . $headers['X-RateLimit-Reset'] . '<br>';
echo '</p>';


At this point, I -was- getting my needed header response data from Vimeo..

but the rest of the JSON data is now gone/doesnt display anymore.

ie:

echo '<h2 class="title">'.$vimeoJSON['name'] . '</h2>';


does show up anymore.

If I comment out this line:
CURLOPT_HEADER => true,

This work again.. (however I do NOT get my header response data from Vimeo anymore.

Question is:


  • How can I update my code to allow for BOTH?? The header response data from Vimeo.. and still be able to use the $vimeoJSON['xxxx'] data that I have riddled throughout my app?



@Taylor

When using your code sample (I know found on the net elsewhere)

//temp
$header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($response, 0, $header_size);
$body = substr($response, $header_size);

echo "HEADER SIZE: " . $header_size . "<br><br>";
echo "HEADER: " . $header . "<br><br>";
echo "BODY: <pre>" . $body . "</pre><br><br>";


doesnt matter if I have verbose or header set to true..

the returned embed code is broken?

Seems to come over with double quotes escaped or something:

^iframe src=\"https://player.vimeo.com/video/171002772?badge=0&autopause=0&player_id=0\" width=\"900\" height=\"450\" frameborder=\"0\" title=\"How to Save A Dying LVAD - Zachary M. Shinar, MD\" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe^


vs

^iframe src="https://player.vimeo.com/video/171002772?badge=0&autopause=0&player_id=0" width="900" height="450" frameborder="0" title="How to Save A Dying LVAD - Zachary M. Shinar, MD" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe^

Answer

CURLOPT_HEADER causes the http headers to become part of the output of curl_exec, which means you're not receiving just JSON anymore, you're receiving headers + Json, e.g.

$response before:

{"foo":"bar"}

$response after:

Header1: value1
header2: value2

{"foo":"bar"}

When you pass that after value directly to json_decode(), it'll barf, because it's NOT valid json anymore. You need to rip off the entire header component from that string, so it's just the plain json string again.

Comments