get_head_headers()
Deze functie vraagt de HTTP headers op van een URI, net zoals get_headers alleen doet deze functie ook werkelijk een HEAD aanvraag waar get_headers een GET-aanvraag doet. Dit is vooral handig voor statische content, zo hoeft Apache bijvoorbeeld niet een bestand klaar te zetten wanneer je alleen maar de last-modified datum wilt weten. PHP wordt (helaas) wel volledig uitgevoerd, tenzij je een slim script hebt dat de HEAD request method afvangt. Ingebakken zit ook de mogelijkheid om redirects te volgen net zoals de standaard functies van PHP doen maar is het resultaat van get_head_headers hier logischer dan die van get_headers (die geeft de headers terug van alle redirects) Hij is bestand tegen oneindige redirect-lussen (bijv. bestanden die via Location naar zichzelf verwijzen, PHP heeft dit zelf ook maar zonder melding en met een maximum van 20 geloof ik) Let op dat het niet een drop-in replacement is; Deze functie heeft als 2e argument of hij wel of niet redirects moet volgen (standaard niet) terwijl de native variant hier de switch heeft om er logische output uit te krijgen.
<?php
define('HTTP_MAX_REDIRECT_COUNT', 5);
define('HTTP_MAX_HEADER_LENGTH', 2560);
define('HTTP_DEFAULT_PORT', 80);
define('HTTP_TIMEOUT', 5);
function get_head_headers($url, $follow_redirect = false) {
static $redirect_count;
if(!is_array($url)) {
$url = parse_url($url);
}
if(!array_key_exists('port', $url)) {
$url['port'] = HTTP_DEFAULT_PORT;
}
if(empty($url['path'])) {
$url['path'] = '/';
}
$socket = @fsockopen($url['host'], $url['port'], $error_no, $error_str, HTTP_TIMEOUT);
if(!$socket) {
throw new LogicException("Could not create connection. Reason: $error_str");
}
$request = sprintf("HEAD %s HTTP/1.1\r\nHost: %s\r\nConnection: Close\r\n\r\n",
$url['path'] . (isset($url['query']) ? '?' . $url['query'] : ''),
$url['host']);
if(!fwrite($socket, $request)) {
throw new LogicException("Could not write to socket. Reason: $error_str");
}
$headers = array();
while(!feof($socket)) {
list($name, $value) = array_merge(explode(':', fgets($socket, HTTP_MAX_HEADER_LENGTH), 2), array(''));
if(!trim($name)) continue;
if($value) {
$headers[trim($name)] = trim($value);
} else {
$headers[] = trim($name); // voor de 1e 200 OK regel
}
}
fclose($socket);
if($follow_redirect && array_key_exists('Location', $headers)) {
if($redirect_count++ >= HTTP_MAX_REDIRECT_COUNT) {
throw new LogicException('Max redirect count reached');
}
$new_url = parse_url($headers['Location']);
if(!isset($new_url['host'])) {
$new_url['host'] = $url['host'];
}
if($new_url['path'][0] != '/') {
$new_url['path'] = dirname($url['path']) . '/' . $new_url['path'];
}
return get_head_headers($new_url, true);
}
$redirect_count = 0;
return $headers;
}
?>
Reacties
0