Как использовать заголовки кэша HTTP с PHP

У меня есть PHP 5.1.0 веб-сайта (на самом деле, это 5.2.9, но он должен также работать 5.1.0 +).

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

Я знаю, что они уже - несколько систем кэша и платформ PHP там, но моему хосту не установили APC или Memcached, и я не использую платформы для этого конкретного проекта.

Я хочу, чтобы страницы кэшировались (я думаю по умолчанию, что PHP "запрещают" кэш). До сих пор я использую:

session_cache_limiter('private'); //Aim at 'public'
session_cache_expire(180);
header("Content-type: $documentMimeType; charset=$documentCharset");
header('Vary: Accept');
header("Content-language: $currentLanguage");

Я прочитал много учебных руководств, но я не могу найти что-то простым (я знаю, что кэш является чем-то сложным, но мне только нужен некоторый основной материал).

То, что, "должно" иметь заголовки для отправки к кэшированию справки?

59
задан James Douglas 9 April 2018 в 20:21
поделиться

4 ответа

Возможно, вы захотите использовать private_no_expire вместо private, но установите длительный срок действия для контента, который, как вы знаете, не изменится, и убедитесь, что вы обрабатываете if-modified-запросы и if-none-match, похожие на сообщение Эмиля.

$tsstring = gmdate('D, d M Y H:i:s ', $timestamp) . 'GMT';
$etag = $language . $timestamp;

$if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
$if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
if ((($if_none_match && $if_none_match == $etag) || (!$if_none_match)) &&
    ($if_modified_since && $if_modified_since == $tsstring))
{
    header('HTTP/1.1 304 Not Modified');
    exit();
}
else
{
    header("Last-Modified: $tsstring");
    header("ETag: \"{$etag}\"");
}

Где $etag может быть контрольной суммой, основанной на содержании или идентификаторе пользователя, языке и метке времени, напр.

$etag = md5($language . $timestamp);
45
ответ дан 24 November 2019 в 18:30
поделиться

У вас должен быть заголовок Expires. Технически, есть и другие решения, но заголовок Expires действительно является лучшим, потому что он говорит браузеру не перепроверять страницу до истечения срока годности и времени, а просто обслуживать содержимое из кэша. Это действительно здорово работает!

Также полезно проверить If-Modified-Since заголовок в запросе браузера. Этот заголовок отправляется, когда браузер "не уверен" в том, что контент в его кэше всё ещё правильная версия. Если с тех пор ваша страница не была изменена, просто отправьте код HTTP 304 (не изменён). Вот пример, который отправляет код 304 в течение десяти минут:

<?php
if(isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) {
  if(strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) < time() - 600) {
    header('HTTP/1.1 304 Not Modified');
    exit;
  }
}
?>

Вы можете включить эту проверку заранее в ваш код, чтобы сэкономить ресурсы сервера.

.
12
ответ дан 24 November 2019 в 18:30
поделиться
<?php
header("Expires: Sat, 26 Jul 2020 05:00:00 GMT"); // Date in the future
?>

Установка даты истечения срока действия для кэшированной страницы является одним из полезных способов кэширования на стороне клиента.

8
ответ дан 24 November 2019 в 18:30
поделиться

Выбирайте - или используйте их все! :-)

header('Expires: Thu, 01-Jan-70 00:00:01 GMT');
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');
7
ответ дан 24 November 2019 в 18:30
поделиться
Другие вопросы по тегам:

Похожие вопросы: