ext/curl is the common tool of choice, if one needs to perform more advanced HTTP requests from a PHP script (for simple ones, use a stream!). I recently wanted to perform a HEAD request to a file, after which I wanted to perform some more advanced HTTP interaction, so CURL was also the tool of choice here.
Trying it out on the shell with a local web server, CURL was operating quite slow, in contrast to a GET request. The -i command line switch makes curl include the headers in the printed output, -X lets you define a custom HTTP request.
dotxp@tango ~ $ time curl -i -X HEAD http://localhost/admin/
HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:10:59 GMT
Server: lighttpd/1.4.19
real 0m6.079s
user 0m0.004s
sys 0m0.000s
dotxp@tango ~ $ time curl -i -X GET http://localhost/admin/
HTTP/1.1 200 OK
Transfer-Encoding: chunked
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:12:27 GMT
Server: lighttpd/1.4.19
<snip content="html source" />
real 0m0.180s
user 0m0.004s
sys 0m0.000s
A difference of 6 seconds runtime of a HEAD in contrast to 0.2 seconds for a GET is quite contrary to the original idea of a HEAD request. HEAD is used to just receive the headers of an URI instead of receiving the whole contents, to save bandwidth, memory and execution time.
ext/curl showed the exact same problem. Fiddling a bit with the command line switches, I found to replace -i with -I which makes curl print only the headers, but not the body of the response.
dotxp@tango ~ $ time curl -I -X HEAD http://localhost/admin/
HTTP/1.1 200 OK
X-Powered-By: PHP/5.2.7-dev
<snip type="more http headers" />
Content-Type: text/html; charset=utf-8
Date: Mon, 23 Jun 2008 09:19:05 GMT
Server: lighttpd/1.4.19
real 0m0.044s
user 0m0.004s
sys 0m0.000s
0.04 seconds is now even faster than the corresponding GET request, with the -I switch, which took me 0.09 seconds. Now I just needed to transfer the command line options to the corresponding ext/curl ones:
$c = curl_init();
curl_setopt( $c, CURLOPT_RETURNTRANSFER, true );
curl_setopt( $c, CURLOPT_CUSTOMREQUEST, 'HEAD' );
curl_setopt( $c, CURLOPT_HEADER, 1 );
curl_setopt( $c, CURLOPT_NOBODY, true );
curl_setopt( $c, CURLOPT_URL, 'http://localhost/admin/' );
$res = curl_exec( $c );
The RETURNTRANSFER makes ext/curl return the HTTP response instead of printing it. Using the CUSTOMREQUEST option you define to send a HEAD request instead of a standard GET or POST request. The HEADER option makes ext/curl include the response headers in the return value of curl_exec() call and NOBODY avoids the inclusion of the body content here. The URL option as usually sets the URL to request and curl_exec() makes ext/curl execute the request.
The runtime was even a fraction of a second faster here, compared to the command line version, but that can be subjectively. However, the HEAD request works as expected now. Maybe it's useful for someone to know this.