После многого поиска, прочитав все обучающие материалы, которые я нашел, и задал несколько вопросов здесь, мне наконец-то удалось ответить (по крайней мере, я думаю) на аргументы if-none-match и if-modified-since HTTP.
Чтобы сделать краткое описание, это то, что я делаю на всех страницах, кэш:
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» будет отображаться по адресу «/ ru / home» на английском языке и «/ fr / accueil» на французском языке.
Моя большая проблема заключалась в том, чтобы ответить на «304 Not Modified» на if-none-match и if-modified-так как HTTP-запросы только тогда, когда это необходимо .
Лучший doc, который я нашел, это: http://rithiur.anthd.com/tutorials/conditionalget.php
И это реализация, которую я сделал с ней (этот фрагмент кода называется ASAP на страницах, которые можно кэшировать):
$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(); } }
Мой вопрос в два раза:
BTW, я использую только PHP 5.1.0+ (я не поддерживаю версии ниже этого).
Изменить: Добавлена баунти … Я ожидаю качественного ответа. Не отвечайте / голосуйте, если вы что-то угадываете!
Вот функция, которая может помочь:
function isModified($mtime, $etag) { return !( ( isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $mtime ) || ( isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag ) ) ; }
Я предлагаю вам взглянуть на следующую статью: http://www.peej.co.uk/articles/http-caching.html
Обновить:
[AlexV] Возможно ли получить if-none-match AND if-modified-так как в то же время?
У вас наверняка есть оба набора. Однако:
Если ни один из тегов сущностей не совпадает, тогда сервер МОЖЕТ выполнить запрошенный метод, как если бы поле заголовка If-None-Match не существовало, но ДОЛЖНО также игнорировать любые поля (-ы) заголовка If-Modified-Since в запросе. То есть, если теги сущностей не совпадают, тогда сервер НЕ ДОЛЖЕН возвращать ответ 304 (не модифицированный).
RFC2616 # 14.26
Примеры значений (W означает «слабый», более подробно читайте в RFC2616 # 13.3.3 ):
If-None-Match: "xyzzy", "r2d2xxxx", "c3piozzzz" If-None-Match: W/"xyzzy", W/"r2d2xxxx", W/"c3piozzzz" If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT If-None-Match: *
В качестве специального случая значение «*» соответствует любому текущему объекту ресурса.