Наверное, каждый веб-программист, интересующийся кешированием веб-страниц
на стороне клиента, знает о таких заголовках HTTP,
как «If-Modified-Since» и «If-None-Match».
Данные заголовки отправляются браузером при обращении к странице,
которая имеется в его кеше. Для правильной организации кеширования на стороне
клиента, серверному приложению необходимо отправлять заголовок
"HTTP/1.0 304 Not Modified"и прекращать передачу данных
в случае, если содержимое запрашиваемой страницы не изменилось с того момента
времени, которое указано в присланном заголовке "If-Modified-Since".
Основная проблема при реализации кеширования на стороне клиента
заключается в том, чтобы получить содержимое заголовка "If-Modified-Since".
Вызвана она тем, что по умолчанию указанный заголовок доступен из серверного
приложения только в том случае, если интерпретатор PHP установлен в качестве
модуля Apache, что бывает крайне редко на серверах организаций,
предлагающих услуги хостинга (по соображениям безопасности и удобства
перекомпиляции PHP). Следует заметить, что кеширование на стороне клиента
благотворно влияет не только на нагрузку веб-сервера, но и на скорость
индексации веб-сайта поисковыми машинами. В связи с этим, опытные SEO-специалисты упорно
ищут и рекомендуют "правильные" хостинговые компании.
На самом деле, существует универсальное решение данной проблемы,
не требующее вмешательства в глобальную конфигурацию веб-сервера и работающее
даже в том случае, когда PHP не установлен в качестве модуля Apache.
Для применения данного метода необходимо и достаточно, чтобы выполнялись
следующие условия:
- возможность конфигурации через
файлы .htaccess;
- доступность и возможность использования
модуля mod_rewrite;
- в серверном приложении к заголовкам "If-Modified-Since" и "If-None-Match"
необходимо обращаться через массив $_SERVER, а не при помощи функций
getallheaders или apache_request_headers
(эти функции доступны только в том случае, если PHP установлен в качестве
модуля Apache).
Итак, для реализации доступа к заголовкам "If-Modified-Since" и "If-None-Match"
необходимо в корневом каталоге веб-сайта поместить файл .htaccess
следующего содержания:
RewriteEngine On
RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]
После этого, необходимые заголовки будут доступны как $_SERVER['HTTP_IF_MODIFIED_SINCE'] и $_SERVER['HTTP_IF_NONE_MATCH']. В случае если на веб-сайте mod_rewrite используется для формирования <красивых> URL, содержимое .htaccess примет вид:
# url rewriting
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA]
# If-Modified-Since (if php is not installed as cgi then comment lines below)
RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}]
RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}]
Следует заметить, что заголовки и не отправляются браузером, если в предыдущих запросах к данной странице он не получал в ответе веб-сервера заголовок <Last-Modified>. Кроме того, при использовании в веб-приложении сессий с установками по умолчанию, указанные заголовки также не будут присылаться браузером. Для того чтобы избежать такого поведения браузера, необходимо перед запуском сессии выполнять функцию session_cache_limiter, передавая в качестве аргумента параметр 'private_no_expire':
<?php
session_cache_limiter('private_no_expire');
session_start();
?>