HTTP HEAD в PHP: Работа с кэшем и ETag

HTTP HEAD – это метод HTTP, который позволяет получить метаданные ресурса (например, дату последнего изменения, тип контента, длину контента) без передачи самого тела ресурса․ В PHP этот метод часто используется для эффективной работы с кэшем и управления версиями ресурсов с помощью ETag․

Зачем использовать HTTP HEAD?

Основное преимущество HTTP HEAD заключается в экономии трафика и времени․ Вместо того, чтобы загружать весь файл, клиент получает только заголовки, что особенно полезно в следующих сценариях:

  • Проверка существования ресурса: Перед загрузкой большого файла можно проверить, существует ли он на сервере․
  • Определение изменений: Клиент может сравнить ETag полученный с помощью HEAD запроса с текущим ETag, чтобы определить, изменился ли ресурс․
  • Оптимизация кэширования: Сервер может указать клиенту, как долго можно кэшировать ресурс, используя заголовки Cache-Control и Expires․

Реализация HTTP HEAD в PHP

PHP автоматически обрабатывает HTTP HEAD запросы, если в вашем скрипте предусмотрена обработка GET запросов․ Когда сервер получает HEAD запрос, он отправляет те же заголовки, что и для GET запроса, но без тела ответа․ Однако, для более точного контроля и оптимизации, можно явно обработать HEAD запрос․

Пример обработки HEAD запроса


<?php
if ($_SERVER['REQUEST_METHOD'] === 'HEAD') {
 // Устанавливаем заголовки header('Content-Length: 0'); // Важно! Указываем длину контента 0
 header('Last-Modified: ' ․ gmdate('D, d M Y H:i:s', time));
 header('ETag: "' ․ md5(file_get_contents('myfile․txt')) ․ '"'); // Пример ETag
 exit;
} else if ($_SERVER['REQUEST_METHOD'] === 'GET') {
 // Обработка GET запроса (обычная загрузка файла)
 echo file_get_contents('myfile․txt');
} else {
 header('Allow: GET, HEAD');
 http_response_code(405);
 echo 'Method Not Allowed';
}
?>

Важно: При обработке HEAD запроса необходимо установить заголовок Content-Length: 0, так как тело ответа не отправляется․ Также, необходимо установить все заголовки, которые вы хотите вернуть клиенту․

Работа с ETag

ETag (Entity Tag) – это уникальный идентификатор ресурса․ Сервер генерирует ETag для каждого ресурса, и клиент может использовать его для проверки, изменился ли ресурс с момента последнего запроса․

Как работает ETag?

  1. Клиент запрашивает ресурс (GET или HEAD)․
  2. Сервер отправляет ресурс и ETag․
  3. Клиент кэширует ресурс и ETag;
  4. При следующем запросе клиент отправляет ETag в заголовке If-None-Match
  5. Если ETag на сервере совпадает с ETag, отправленным клиентом, сервер отправляет ответ со статусом 304 Not Modified без тела ответа․
  6. Если ETag не совпадает, сервер отправляет ресурс и новый ETag․

Пример использования ETag в PHP


<?php
$file = 'myfile․txt';
$etag = md5(file_get_contents($file));

if ($_SERVER['REQUEST_METHOD'] === 'GET') {
 if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] === $etag) {
 header('HTTP/1․1 304 Not Modified');
 exit;
 } else {
 header('ETag: "' ․ $etag ․ '"');
 echo file_get_contents($file);
 }
} else if ($_SERVER['REQUEST_METHOD'] === 'HEAD') { header('Content-Length: 0');
 header('Last-Modified: ' ․ gmdate('D, d M Y H:i:s', time));
 header('ETag: "' ․ $etag ․ '"');
 exit;
} else {
 header('Allow: GET, HEAD');
 http_response_code(405);
 echo 'Method Not Allowed';
}
?>

HTTP HEAD – это мощный инструмент для оптимизации работы с кэшем и управления версиями ресурсов в PHP․ Использование ETag позволяет значительно снизить нагрузку на сервер и ускорить загрузку страниц для пользователей․ Правильная реализация HTTP HEAD и ETag может существенно улучшить производительность вашего веб-приложения․