Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can PHP cURL retrieve response headers AND body in a single request?

Tags:

http

php

curl

Is there any way to get both headers and body for a cURL request using PHP? I found that this option:

curl_setopt($ch, CURLOPT_HEADER, true); 

is going to return the body plus headers, but then I need to parse it to get the body. Is there any way to get both in a more usable (and secure) way?

Note that for "single request" I mean avoiding issuing a HEAD request prior of GET/POST.

like image 708
gremo Avatar asked Feb 07 '12 20:02

gremo


People also ask

How do I get response headers in cURL?

We can use curl -v or curl -verbose to display the request headers and response headers in the cURL command. The > lines are request headers . The < lines are response headers .

How can I get response header in PHP?

There is a simple solution built into cURL if you are only interested in the response headers and not the content of the body. By setting the CURLOPT_HEADER and CURLOPT_NOBODY options to true, the result of curl_exec() will only contain the headers.

What does PHP cURL return?

Functions of cURL in PHP curl_error — It will return the string which represents the error for the particular current session.


2 Answers

One solution to this was posted in the PHP documentation comments: http://www.php.net/manual/en/function.curl-exec.php#80442

Code example:

$ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 1); // ...  $response = curl_exec($ch);  // Then, after your curl_exec call: $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $header_size); $body = substr($response, $header_size); 

Warning: As noted in the comments below, this may not be reliable when used with proxy servers or when handling certain types of redirects. @Geoffrey's answer may handle these more reliably.

like image 107
iblue Avatar answered Sep 22 '22 22:09

iblue


Many of the other solutions offered this thread are not doing this correctly.

  • Splitting on \r\n\r\n is not reliable when CURLOPT_FOLLOWLOCATION is on or when the server responds with a 100 code.
  • Not all servers are standards compliant and transmit just a \n for new lines.
  • Detecting the size of the headers via CURLINFO_HEADER_SIZE is also not always reliable, especially when proxies are used or in some of the same redirection scenarios.

The most correct method is using CURLOPT_HEADERFUNCTION.

Here is a very clean method of performing this using PHP closures. It also converts all headers to lowercase for consistent handling across servers and HTTP versions.

This version will retain duplicated headers

This complies with RFC822 and RFC2616, please do not suggest edits to make use of the mb_ string functions, it is incorrect!

$ch = curl_init(); $headers = []; curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  // this function is called by curl for each header received curl_setopt($ch, CURLOPT_HEADERFUNCTION,   function($curl, $header) use (&$headers)   {     $len = strlen($header);     $header = explode(':', $header, 2);     if (count($header) < 2) // ignore invalid headers       return $len;      $headers[strtolower(trim($header[0]))][] = trim($header[1]);      return $len;   } );  $data = curl_exec($ch); print_r($headers); 
like image 27
Geoffrey Avatar answered Sep 24 '22 22:09

Geoffrey