沃梦达 / 编程问答 / php问题 / 正文

我在 PHP 中执行 HTTP Conditional Get answers 是否可以?

Is my implementation of HTTP Conditional Get answers in PHP is OK?(我在 PHP 中执行 HTTP Conditional Get answers 是否可以?)

本文介绍了我在 PHP 中执行 HTTP Conditional Get answers 是否可以?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

经过大量搜索,阅读了我找到的每个教程并在这里提出了一些问题,我终于设法正确地回答了(至少我认为)if-none-match 和 if-modified-since HTTP 请求.

After searching a lot, reading every tutorials I've found and asking some questions here, I've finally managed to answer corrctly (at least I think) to if-none-match and if-modified-since HTTP requests.

简要回顾一下,这是我对每个可缓存页面所做的:

To do a quick recap, this is what I do on every pages cacheable:

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"和法文 URL/fr/accueil"下提供.

Also, every page have it's own URL (for every languages). For example, "index.php" will be served under URL "/en/home" in English and "/fr/accueil" in French.

我的大问题是仅在需要时回答304 Not Modified"到 if-none-match 和 if-modified-since HTTP 请求.

My big problem was to answer a "304 Not Modified" to if-none-match and if-modified-since HTTP requests only when needed.

我找到的最好的文档是:http://rithiur.anthd.com/tutorials/conditionalget.php

The best doc I've found is: http://rithiur.anthd.com/tutorials/conditionalget.php

这是我对它的实现(这段代码在可以缓存的页面上被称为 ASAP):

And this is the implementation I did of it (this piece of code is called ASAP on pages that can be cached):

$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 时,both 必须匹配才能回答 304,如果只发送两者中的一个,则只匹配这个就可以发送304?
  • 在此处描述的上下文中使用时,这 2 个片段是否对公共缓存友好(我的意思是代理 Web 浏览器上的缓存友好)?
  • Is it the correct way to do it? I mean when if-none-match and if-modified-since are sent, both must match to answer a 304, and if only one of the two is sent, only matching this one is OK to send a 304?
  • When used in the context described here, is these 2 snippets are public cache friendly (I mean cache friendly on proxies and Web browsers)?

顺便说一句,我只使用 PHP 5.1.0+(我不支持低于该版本的版本).

BTW, I use PHP 5.1.0+ only (I don't support versions lower that that).

增加了赏金...我希望得到高质量的答案.如果您猜到了什么,请不要回答/投票!

Added bounty... I expect quality answer. Don't answer/vote if you are guessing something!

推荐答案

  • 这不太正确.请看一下算法:alt text http://img532.imageshack.us/img532/1017/cache.png
  • 该解决方案对代理友好,您可以使用 Cache-control: proxy-revalidate 来强制缓存遵循您提供的有关资源的任何新鲜信息(仅适用于共享|代理缓存)
  • 以下是可能有帮助的功能:

    Here is the function that might help:

    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

    I suggest that you take a look at the following article: http://www.peej.co.uk/articles/http-caching.html

    更新:

    [AlexV] 甚至可以同时接收 if-none-match 和 if-modified-since 吗?

    [AlexV] Is is even possible to receive if-none-match AND if-modified-since at the same time?

    你绝对可以同时设置.然而:

    You can definitely have both set. However:

    如果没有一个实体标签匹配,那么服务器可以执行请求的方法,就好像 If-None-Match 头域不存在,但也必须忽略任何 If-Modified-Since 头域在要求.也就是说,如果没有实体标签匹配,则服务器不得返回 304(未修改)响应.

    If none of the entity tags match, then the server MAY perform the requested method as if the If-None-Match header field did not exist, but MUST also ignore any If-Modified-Since header field(s) in the request. That is, if no entity tags match, then the server MUST NOT return a 304 (Not Modified) response.

    RFC2616 #14.26

    示例值(W 代表弱";在 RFC2616 #13.3.3):

    Example values (W stands for 'weak'; read more in 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: *
    

    作为一种特殊情况,值*"是匹配资源的任何当前实体.

    As a special case, the value "*" matches any current entity of the resource.

    这篇关于我在 PHP 中执行 HTTP Conditional Get answers 是否可以?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:我在 PHP 中执行 HTTP Conditional Get answers 是否可以?

基础教程推荐