Ключевые слова:php, web, apache, cache, mod_rewrite, (найти похожие документы)
From: Николай И. Яровой <nikolay@controlstyle.ru.>
Newsgroups: email
Date: Mon, 3 May 2006 14:31:37 +0000 (UTC)
Subject: Заголовок If-Modified-Since, если PHP не установлен как модуль Apache
Оригинал статьи доступен по адресу:
http://www.controlstyle.ru/articles/programming/text/if-mod-since-php/
Наверное, каждый веб-программист, интересующийся кешированием
веб-страниц на стороне клиента, знает о таких заголовках 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}]
Следует заметить, что заголовки "If-Modified-Since" и "If-None-Match" не
отправляются браузером, если в предыдущих запросах к данной странице он
не получал в ответе веб-сервера заголовок Last-Modified. Кроме того, при
использовании в веб-приложении сессий с установками по умолчанию,
указанные заголовки также не будут присылаться браузером. Для того чтобы
избежать такого поведения браузера, необходимо перед запуском сессии
выполнять функцию session_cache_limiter, передавая в качестве аргумента
параметр 'private_no_expire':
<?php
session_cache_limiter('private_no_expire');
session_start();
?>