当前位置:  开发笔记 > 编程语言 > 正文

如何在PHP中使用HTTP缓存头

如何解决《如何在PHP中使用HTTP缓存头》经验,为你挑选了5个好方法。

我有一个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");

我读了很多教程,但是我找不到简单的东西(我知道缓存是复杂的,但我只需要一些基本的东西).

什么是"必须"有标题发送来帮助缓存?



1> Steve-o..:

您可能希望使用private_no_expire而不是private,但为您知道不会更改的内容设置较长的过期时间,并确保您处理if-modified-sinceif-none-match请求类似于Emil的帖子.

$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可以是基于内容或用户ID,语言和时间戳的校验和,例如

$etag = md5($language . $timestamp);


如果您没有使用上述304,请检查HTTP_IF_NONE_MATCH中是否存在任何杂散引号.用'rtrim(ltrim($ if_none_match,"'\""),"'\"")== $ etag`替换`$ if_none_match == $ etag`以确定.
你所描述的将是一个弱电子标签,并且应该有一个"W /"前缀.
`$ timestamp`来自哪里?应该在代码的其余部分`$ timestamp = time();之前定义吗?我错过了什么吗?

2> Emil Vikströ..:

您必须有一个Expires标头.从技术上讲,还有其他解决方案,但Expires标头实际上是最好的,因为它告诉浏览器在到期日期和时间之前不重新检查页面,只是从缓存中提供内容.它真的很棒!

在浏览器的请求中检查If-Modified-Since标头也很有用.当浏览器"不确定"时,如果其缓存中的内容仍然是正确的版本,则会发送此标头.如果您的页面从那时起未被修改,则只需发回HTTP 304代码(未修改).这是一个发送304代码十分钟的示例:


您可以在代码中尽早进行此检查以节省服务器资源.



3> S Pangborn..:

设置缓存页面的到期日期是在客户端缓存它的一种有用方法.



4> 小智..:

随你挑 - 或全部使用!:-)

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');



5> Jasper..:

这是一个为您提供http缓存的小类.它有一个名为'Init'的静态函数,需要2个参数,上次修改页面(或浏览器请求的任何其他文件)的日期的时间戳,以及此页面可以保存的最大年龄(以秒为单位)通过浏览器缓存.

class HttpCache 
{
    public static function Init($lastModifiedTimestamp, $maxAge)
    {
        if (self::IsModifiedSince($lastModifiedTimestamp))
        {
            self::SetLastModifiedHeader($lastModifiedTimestamp, $maxAge);
        }
        else 
        {
            self::SetNotModifiedHeader($maxAge);
        }
    }

    private static function IsModifiedSince($lastModifiedTimestamp)
    {
        $allHeaders = getallheaders();

        if (array_key_exists("If-Modified-Since", $allHeaders))
        {
            $gmtSinceDate = $allHeaders["If-Modified-Since"];
            $sinceTimestamp = strtotime($gmtSinceDate);

            // Can the browser get it from the cache?
            if ($sinceTimestamp != false && $lastModifiedTimestamp <= $sinceTimestamp)
            {
                return false;
            }
        }

        return true;
    }

    private static function SetNotModifiedHeader($maxAge)
    {
        // Set headers
        header("HTTP/1.1 304 Not Modified", true);
        header("Cache-Control: public, max-age=$maxAge", true);
        die();
    }

    private static function SetLastModifiedHeader($lastModifiedTimestamp, $maxAge)
    {
        // Fetching the last modified time of the XML file
        $date = gmdate("D, j M Y H:i:s", $lastModifiedTimestamp)." GMT";

        // Set headers
        header("HTTP/1.1 200 OK", true);
        header("Cache-Control: public, max-age=$maxAge", true);
        header("Last-Modified: $date", true);
    }
}

推荐阅读
惬听风吟jyy_802
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有