Search code examples
phpjsoncurlvimeo

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^

Solution

  • 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.