Sunday, July 20, 2008

PHP: Get server response header by request HEAD


Share at Facebook

You can use CURL 'curl_setopt' option to get the server response HEADER without loading the whole page. When you fetch a webpage using CURL, it will automatically load the whole HTML page with the server response header. But I'll tell you how to use CURL to call only the header and ignore the HTML source loading.

There is an option for 'curl_setopt()' is CURLOPT_CUSTOMREQUEST. Using this you can customize the HTTP Request. If you do not set any value for this option, the default request will always be GET. For our purpose, we'll set this with HEAD to request only for header from the remote server. There is another option for 'curl_setopt()' is CURLOPT_HEADER. This option will return the HEADERs if it is set as true or 1. So combination of both of this will be,

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

Combining both of them will request for HEADER and return the hedaer into a variable. Now lets call the google for HEAD, and here is the complete code.
$url = 'http://www.google.com/';

$ch = curl_init();
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt ($ch, CURLOPT_CONNECTTIMEOUT, 20);
curl_setopt ($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.11) Gecko/20071127 Firefox/2.0.0.11');

// Only calling the head
curl_setopt($ch, CURLOPT_HEADER, true); // header will be at output
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HTTP request is 'HEAD'

$content = curl_exec ($ch);
curl_close ($ch);

print $content;

Execution of this code will return the headers from google.

If you are not expert on CURL, or do not like to use the CURL. Then you can use fsockopen() function to request for HEADER from server. Below is the code that will request to hotmail.com for header and print it.
$domain = "www.hotmail.com";
$portno = 80;
$method = "HEAD";
$url = "/";

$http_response = "";
$http_request .= $method." ".$url ." HTTP/1.0\r\n";
$http_request .= "\r\n";

$fp = fsockopen($domain, $portno, $errno, $errstr);
if($fp){
fputs($fp, $http_request);
while (!feof($fp)) $http_response .= fgets($fp, 128);
fclose($fp);
}
print $http_response;

Remember, I didn't add the useragent and other request headers while using fsockopen() function. Response from server may vary if you don't use header. Like wikipedia used to redirect for unlimited times if you don't use any useragent. If you want to add request header, then you need to add this like as below.
$http_request.= "Content-type: application/x-www-form-urlencoded\r\n";
$http_request.= "Cache-Control: no-cache\r\n";
$http_request.= "User-Agent: MSIE\r\n";
$http_request.= "Connection: close\r\n";

Thats it. If you want to learn more about PHP, here is my other topics http://icfun.blogspot.com/search/label/php




6 comments:

Scuzzy said...

you're a life saver buddy thanks. just wondering... how about if i want to know only some part of the header, i mean.. like getting just the content-length? sorry i'm just a beginner :)

Wolf said...

Change the value of header, and modify the function if you need.


$header = "set-cookie";
print parse_header($content, $header);

$header = "date";
print parse_header($content, $header);

// function takes HTTP response header, and the header name
// return the valus/values of the header name
function parse_header($content, $header){
$ret_str = "";
if( preg_match_all("/($header.*)/i",$content, $match ) ){
$match = $match[1];
foreach( $match as $str){
$ret_str .= $str . "\n";
}
}
return $ret_str;
}

Scuzzy said...

wow you really impress me buddy :D works like a charm! and it fits perfectly on my script i don't even have to change anything! well.. i modified it a bit so i can get only the value. thank you very much wolf i learned so much and got the concept of parsing strings. i owe you one ;)

Dimitry said...

Spent two days to find this article. Exactly what I need! Thank you very much!

subeen said...

I was looking for how to do head call using PHP / CURL, and found this post very useful. Thanks.

Mrinal Mukherjee said...

I was designing a system monitor which hits maybe a 100 URLs after every 5 minutes to check whether the URL is working.

I used the following code to test this function bu hitting google.com using a loop -

$time_start = microtime_float();
for ($i=0; $i < 50; $i++)
{
$ch = curl_init('http://google.com/');
curl_setopt($ch, CURLOPT_NOBODY, 1);
$c = curl_exec($ch);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE);
}
$time_end = microtime_float();
$time = $time_end - $time_start;
echo "Executed in $time seconds\n";

However, this takes around 50-55 seconds to execute. Is there a quicker way we could do this?