Serious shortcomings with PHP5 get_headers() function

I was writing some code to find out if a file exists on a server and if it does, have it return the size in bytes.  I found a useful function built into PHP 5, get_headers().  For getting file sizes, it works flawlessly.  For situations where the file does not exist on the server, the behavior of this function was less than desirable.

Be forewarned, none of the user contributed get_headers() functions on the get_headers() documentation page on PHP.net will replicate the behavior of PHP 5’s get_headers() for URLs that use the ‘Location:’ redirect header or return File Not Found headers.

According to RFC1945, A user agent should never automatically redirect a request more than 5 times, since such redirections usually indicate an infinite loop.  For true compatibility, the functions below should be able to handle up to 5 Location redirects within one function call.  Only the native get_headers() function exhibits this behavior.  None of the user contributed functions on PHP.net handle the ‘Location’ redirection.

The native PHP >= 5 get_headers() function will not return headers in some instances where the user contributed functions would.  For example, if the server returns a 404 status, get_headers() will throw a PHP warning.  Unfortunately, the 404 error can only be known by looking at the headers.  From first glance, all of the user contributed functions will return 404 headers, which may be a desired effect but does not replicate the behavior of the native get_headers() function.

The function I created is included below.  It works well if the file exists.  Unfortunately for the project I am using the code for, I also need to verify if the file exists on the server.  I will not be able to use this function.

<CODE>
function remotefsize($url) {
$sch = parse_url($url, PHP_URL_SCHEME);
if (($sch != “http”) && ($sch != “https”) ) {
return false;
}
$headers = array_change_key_case(get_headers($url, 1),CASE_LOWER);
if ((!array_key_exists(“content-length”, $headers)))
return false;
if( is_array($headers[“content-length”]) )
return array_pop($headers[“content-length”]);
return $headers[“content-length”];
}
</CODE>

Leave a Reply

Your email address will not be published. Required fields are marked *