Выдача HTTP-заголовков
Хотя выдача HTTP-заголовков на первый взгляд кажется очень простой задачей, в ней имеется ряд тонкостей:
- Статусы кроме числового кода имеют еще и стандартизированное словесное описание, которое также следует отдавать в строке статуса.
- Отдавать заголовок желательно в той же версии протокола, в которой был сделан запрос (в противном случае возможны проблемы с некоторыми старыми proxy-серверами).
- Некоторые дополнительные поля (например, ETag или Expires) есть только в версии HTTP 1.1.
Ниже приведен пример кода, который реализует корректную выдачу основных HTTP-заголовков (статус передается в $GLOBALS['status'], адрес перехода, если требуется, в $GLOBALS['location'], MD5-хеш отдаваемого документа — в $hash, дата последней модификации — в $GLOBALS['lastmod']). Код возвращает true, если требуется выдача тела документа и false в противном случае.
// выдача статусов
if ($GLOBALS['status']==204) {
header($_SERVER['SERVER_PROTOCOL'].' 204 No Content');
ob_end_clean();
return false;
}
elseif ($GLOBALS['status']==304) {
header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
header('Last-Modified: '.date('r',$GLOBALS['lastmod']));
if ($_SERVER['SERVER_PROTOCOL']=='HTTP/1.1') header('ETag:'.$hash); // для HTTP 1.1 выдаем ETag (MD5-хеш от страницы)
ob_end_clean();
return false;
}
elseif ($GLOBALS['status']==301) {
header($_SERVER['SERVER_PROTOCOL'].' 301 Moved Permanently');
if (isset($GLOBALS['location'])) header('Location: '.$GLOBALS['location']);
return false;
}
elseif ($GLOBALS['status']==302) {
header($_SERVER['SERVER_PROTOCOL'].' 302 Moved Temporary');
if (isset($GLOBALS['location'])) header('Location: '.$GLOBALS['location']);
return false;
}
elseif ($GLOBALS['status']==404) header($_SERVER['SERVER_PROTOCOL'].' 404 Not Found');
elseif ($GLOBALS['status']==503) header($_SERVER['SERVER_PROTOCOL'].' 503 Service Unavailable');
elseif ($GLOBALS['status']==410) header($_SERVER['SERVER_PROTOCOL'].' 410 Gone');
else header($_SERVER['SERVER_PROTOCOL'].' 200 OK');
header('Content-Type: text/html; charset='.$GLOBALS['config']['charset']);
if ($length) header('Content-length: '.$length);
header('Last-Modified: '.date('r',$GLOBALS['lastmod']));
if ($_SERVER['SERVER_PROTOCOL']=='HTTP/1.1') header('ETag:'.$hash); // для HTTP 1.1 выдаем ETag (MD5-хеш от страницы)
if (strtoupper($_SERVER['REQUEST_METHOD'])=='HEAD') return false;
return true;
Метки: статус