Intereting Posts
Копировать код между несколькими PHP-сайтами Ошибка PDO: prepare () с несколькими запросами не работает внутри транзакции Выполнение SOAP-вызова в PHP и установка версии SSL PHP register_shutdown_function для запуска, когда сценарий убит из командной строки? Проверить несколько значений php array PHP-браузер и os-обнаружение, показывающие хром вместо оперы Изменение вложенного (многомерного) массива в пары ключ => значение в PHP тип контента 'text / xml; charset = utf-8 'не был ожидаемым типом' application / soap + xml; кодировка = UTF-8' Лучшее решение для защиты PHP-кода без шифрования Вырезать HTML и специальные символы Почему я не могу перегружать конструкторы в PHP? CSS-фоновые изображения в WordPress API Google Кошелька и PHP, обработка почтовых сообщений Как использовать Imagick для слияния и маскировки изображений? Выполнение нескольких скриптов PHP параллельно и уведомление при завершении

Отвечая на HTTP_IF_MODIFIED_SINCE и HTTP_IF_NONE_MATCH в PHP

У меня есть кешируемое динамическое содержимое, сделанное в PHP 5.1.0+. Я уже отправляю правильные заголовки (включая Last-Modified и ETag) клиентам.

Теперь я хочу, чтобы мой скрипт мог отвечать на $_SERVER['HTTP_IF_MODIFIED_SINCE'] и $_SERVER['HTTP_IF_NONE_MATCH'] при наличии. Когда условия совпадают, я хочу ответить на HTTP 304 "Not Modified" для клиентов.

Каковы правильные условия? Когда именно я выдаю 304 вместо всего контента?

Принятый ответ на вопрос Как узнать, когда отправлять 304 Not Modified ответ, кажется, это правильно, но мне трудно переносить этот код на PHP 5.

Спасибо!

Related of "Отвечая на HTTP_IF_MODIFIED_SINCE и HTTP_IF_NONE_MATCH в PHP"

Я всегда использовал:

 function caching_headers ($file, $timestamp) { $gmt_mtime = gmdate('r', $timestamp); header('ETag: "'.md5($timestamp.$file).'"'); header('Last-Modified: '.$gmt_mtime); header('Cache-Control: public'); if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) { if ($_SERVER['HTTP_IF_MODIFIED_SINCE'] == $gmt_mtime || str_replace('"', '', stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])) == md5($timestamp.$file)) { header('HTTP/1.1 304 Not Modified'); exit(); } } } 

Не помню, писал ли я его или получил его откуда-то еще …

Обычно я использую его в верхней части файла таким образом:

 caching_headers ($_SERVER['SCRIPT_FILENAME'], filemtime($_SERVER['SCRIPT_FILENAME'])); 

Ответ, на который вы ссылаетесь, кажется, содержит все, что вам нужно. Обобщить:

  • создайте свои собственные заголовки ETag и Last-Modified, как если бы вы отправили все тело
  • посмотрите на заголовок If-Modified-Since, отправленный клиентом, если ваш собственный последний модифицированный файл старше или тот же, отправьте сообщение 304
  • посмотрите заголовок If-None-Match клиента, если он соответствует вашему собственному ETag, отправьте сообщение 304
  • если вы дойдете до этого места, заголовки не совпадают, отправьте полное тело и новые заголовки ETag / Last-Modified

Вот фрагмент моей функции render_file ().

 $last_modified = filemtime($filename); if ($last_modified === false) { throw new Exception('Modify date unknown'); } if (array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER)) { $if_modified_since = strtotime(preg_replace('/;.*$/', '', $_SERVER['HTTP_IF_MODIFIED_SINCE'])); if ($if_modified_since >= $last_modified) { // Is the Cached version the most recent? header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified'); exit(); } } header('Last-Modified: '.date('r', $last_modified)); // tz should be GMT according to specs but also works with other tzs // other headers and contents go here 

Если клиент выполнил условный запрос GET и разрешен доступ, но документ не был изменен, сервер ДОЛЖЕН ответить этим кодом состояния. Ответ 304 НЕ ДОЛЖЕН содержать тело сообщения и, таким образом, всегда заканчивается первой пустой строкой после полей заголовка.

От: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.3.5

Итак, если вы отправляете 304, не отправляйте тело.

Эта статья ответит на все ваши вопросы по кешированию

Я обнаружил, что добавление

 RewriteRule .* - [E=HTTP_IF_MODIFIED_SINCE:%{HTTP:If-Modified-Since}] RewriteRule .* - [E=HTTP_IF_NONE_MATCH:%{HTTP:If-None-Match}] 

В нижней части моего файла htaccess (ниже всех переписывающих) работал.

Зачем?

Проведя много исследований по этому вопросу, я обнаружил, что условные запросы фактически замедляют работу сайта. Существуют определенные сценарии, в которых это не так, но в общем случае использование общих шаблонов использования приводит к снижению пропускной способности и менее эффективному кэшированию.

C.