После поиска много, чтения каждого учебные руководства я нашел и задающий некоторые вопросы здесь, мне наконец удалось ответить на corrctly (по крайней мере, я думаю) к 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" будет подаваться под URL "/en/home" на английском и "/fr/accueil" на французском языке.
Моя большая проблема состояла в том, чтобы ответить на "304, Не Измененные" к if-none-match и if-modified-since Запросам HTTP только при необходимости.
Лучший документ, который я нашел: 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();
}
}
Мой вопрос два, свернитесь:
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 не существует, но также должен также игнорировать любые модифицированные по полям заголовка. по запросу. То есть, если никаких меток сущности совпадают, то сервер не должен возвращать 304 (не измененный) ответ.
Пример значений (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: *
как особый случай, значение «*» соответствует любому Текущий объект ресурса.