После долгих поисков, прочитав все учебники, которые я нашел, и задав несколько вопросов здесь, мне наконец удалось правильно ответить (по крайней мере, я так думаю) на HTTP-запросы if-none-match и if-updated-Since.
Чтобы сделать быстрое резюме, вот что я делаю на каждые кешируемые страницы:
session_cache_limiter('public'); //Cache on clients and proxies
session_cache_expire(180); //3 hours
header('Content-Type: ' . $documentMimeType . '; charset=' . $charset);
header('ETag: "' . $eTag . '"'); //$eTag is a MD5 of $currentLanguage + $lastModified
if ($isXML)
header('Vary: Accept'); //$documentMimeType can be either application/xhtml+xml or text/html for XHTML (based on $_SERVER['HTTP_ACCEPT'])
header('Last-Modified: ' . $lastModified);
header('Content-Language: ' . $currentLanguage);
Кроме того, каждая страница имеет свой собственный URL (для всех языков). Например, «index.php» будет обслуживаться по URL-адресу «/ en / home» на английском языке и «/ fr / accueil» на французском.
Моя большая проблема заключалась в том, чтобы ответить «304 Not Modified» на HTTP-запросы if-none-match и if-Modified-начиная с только при необходимости .
Лучший документ, который я нашел:
http://rithiur.anthd.com/tutorials/conditionalget.php
И это реализация, которую я сделал (этот фрагмент кода называется как можно скорее на страницах, которые можно кэшировать):
$ifNoneMatch = array_key_exists('HTTP_IF_NONE_MATCH', $_SERVER) ? $_SERVER['HTTP_IF_NONE_MATCH'] : false;
$ifModifiedSince = array_key_exists('HTTP_IF_MODIFIED_SINCE', $_SERVER) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : false;
if ($ifNoneMatch !== false && $ifModifiedSince !== false)
{
//Both if-none-match and if-modified-since were received.
//They must match the document values in order to send a HTTP 304 answer.
if ($ifNoneMatch == $eTag && $ifModifiedSince == $lastModified)
{
header('Not Modified', true, 304);
exit();
}
}
else
{
//Only one header received, it it match the document value, send a HTTP 304 answer.
if (($ifNoneMatch !== false && $ifNoneMatch == $eTag) || ($ifModifiedSince !== false && $ifModifiedSince == $lastModified))
{
header('Not Modified', true, 304);
exit();
}
}
У меня вопрос в два раза:
- Это правильный способ сделать это? Я имею в виду, что если отправлены if-none-match и if-Modified-Since, оба должны совпадать, чтобы ответить на 304, и если отправляется только один из двух, то только для совпадения можно отправить 304
- При использовании в контексте, описанном здесь, эти 2 фрагмента являются общедоступными для кеша (я имею в виду кеш для прокси и веб-браузеров)?
Кстати, я использую только PHP 5.1.0+ (я не поддерживаю версии ниже этой).
Редактировать: Добавлена награда ... Я ожидаю качественного ответа. Не отвечайте / голосуйте, если вы что-то угадываете!