Drawing on @Geoffrey excellent answer in this thread...
Some 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.
- 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 reliable method of obtaining headers is using CURLOPT_HEADERFUNCTION
. Then you can remove curl_setopt($ch, CURLOPT_HEADER, 1);
and your body will be clean with no headers.
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.
$ch = curl_init();
$headers = [];
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Run the following function for each header received
// Note: Does NOT handle multiple instances of the same header. Later one will overwrite.
// Consider handling that scenario if you need it.
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use (&$headers) {
$len = strlen($header);
$header = explode(':', $header, 2);
if (count($header) >= 2)
$headers[strtolower(trim($header[0]))] = trim($header[1]);
return $len;
});
$data = curl_exec($ch);
print_r($headers);