Skip to content

Instantly share code, notes, and snippets.

@CodeAngry
Created October 4, 2012 19:01
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CodeAngry/3835690 to your computer and use it in GitHub Desktop.
Save CodeAngry/3835690 to your computer and use it in GitHub Desktop.
Alternative to get_headers with cURL and more bling.
<?php
/**
* Does a cURL request against a URL and returns only the Headers.
* If redirections occur, all Headers are returned for each Hop.
*
* By default, if not false, returned value is an array of arrays.
* If $associative is true, each set of Headers will be decoded into an associative array.
* If $only_last is true, regardless of the sets of Headers returned, only the last is kept.
*
* <code>
* If $only_last is false the return is array(
* array(
* 'HeaderName' => 'HeaderValue',
* ...
* )
* )
* </code>
*
* If $only_last is true the return is:
* <code>
* array(
* 'HeaderName' => 'HeaderValue',
* ...
* )
* </code>
*
* Some special properties are available in the Headers array() but I'll let you discover that.
* All special headers are named with X:* and contain important values not in headers.
*
* Testing Code with google.com as 'victim' :)
* <code>
* header('Content-Type: text/plain');
* echo '!$associative + !$only_last', PHP_EOL;
* var_export(get_headers_curl('http://google.com/', false, false));
* echo PHP_EOL, '// ', str_pad(null, 75, '-'), ' //', PHP_EOL;
* echo '!$associative + $only_last', PHP_EOL;
* var_export(get_headers_curl('http://google.com/', false, true));
* echo PHP_EOL, '// ', str_pad(null, 75, '-'), ' //', PHP_EOL;
* echo '$associative + !$only_last', PHP_EOL;
* var_export(get_headers_curl('http://google.com/', true, false));
* echo PHP_EOL, '// ', str_pad(null, 75, '-'), ' //', PHP_EOL;
* echo '$associative + $only_last', PHP_EOL;
* var_export(get_headers_curl('http://google.com/', true, true));
* </code>
*
* @copyright Claude "CodeAngry" Adrian
* @link http://codeangry.com/
*
* @param string $url
* @param bool $associative
* @param bool $only_last
* @param callback $setup_curl
* @return array/false
*/
function get_headers_curl($url, $associative = false, $only_last = true, $setup_curl = null){
if(!is_string($url) or !strlen($url = trim($url))){
trigger_error('$url must be a non-empty trimmed string.', E_USER_WARNING);
return false;
}
if(!preg_match('~^https?://[^\\s]+~i', $url)){
trigger_error('$url must be a valid URL.', E_USER_WARNING);
return false;
}
if(!extension_loaded('curl')){
trigger_error('cURL extension must be loaded.', E_USER_WARNING);
return false;
}
if(!is_resource($ch = curl_init($url))){
trigger_error('curl_init() failed.', E_USER_WARNING);
return false;
}
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
if($setup_curl and is_callable($setup_curl)){
call_user_func($setup_curl, $ch);
}
$response_buckets = array();
if(is_string($response = curl_exec($ch))){
$response = preg_split('~\r?\n~', $response);
$response_buckets = $response_bucket = array();
foreach($response as $response_line){
if(empty($response_line)){
if(empty($response_bucket)){
continue;
}
$response_buckets[] = $response_bucket;
$response_bucket = array();
continue;
}
$response_bucket[] = $response_line;
}
if(!empty($response_bucket)){
$response_buckets[] = $response_bucket;
$response_bucket = array();
}
if($associative){
foreach($response_buckets as $response_key => $response_bucket){
$response_bucket_formatted = array();
foreach($response_bucket as $response_line){
if(preg_match('~^HTTP/([0-9]+\\.[0-9]+)\\s+([0-9]+)\\s+(.+)~', $response_line, $slices)){
$response_bucket_formatted['X:ProtocolVersion'] = $slices[1];
$response_bucket_formatted['X:StatusCode'] = intval($slices[2]);
$response_bucket_formatted['X:StatusMessage'] = trim($slices[3]);
continue;
}
if(preg_match('~^(.+?):(.+)$~', $response_line, $slices)){
$header_name = trim($slices[1]);
$header_value = trim($slices[2]);
if(!empty($response_bucket_formatted[$header_name])){
if(!is_array($response_bucket_formatted[$header_name])){
$response_bucket_formatted[$header_name] = array($response_bucket_formatted[$header_name]);
}
$response_bucket_formatted[$header_name][] = $header_value;
continue;
}
$response_bucket_formatted[$header_name] = $header_value;
}
$response_buckets[$response_key] = $response_bucket_formatted;
}
}
$response_bucket = &$response_buckets[count($response_buckets) - 1];
$response_bucket['X:RequestedUrl'] = curl_getinfo($ch, $url);
$response_bucket['X:EffectiveUrl'] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL);
$response_bucket['X:HttpCode'] = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$response_bucket['X:cURL'] = curl_getinfo($ch);
}
}
curl_close($ch);
return $only_last ? end($response_buckets) : $response_buckets;
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment