深入PHP与浏览器缓存的分析_php实例

我们往往在服务器上对缓存设置进行各种优化方案,但是我们却很少注意到客户端缓存,准确的说是浏览器的缓存机制。
其实每种浏览器都有缓存策略,会暂时将每一个浏览过的文件缓存在一个特殊的文件夹里。我们就可以在用户重复提交页面请求的时候,告诉用户这个页 面没有改变,可以调用缓存。 那我们怎么知道用户有没有这个页面的缓存数据呢? 其实浏览器在发送请求的时候会先发送http头,一般象这样:
Date: Sun, 30 Jul 2006 09:18:11 GMT
Content-Type: image/gif
Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT
ETag: "8c55da8d6abc61:2327"
Content-Length: 14757
其中
Last-Modified: Wed, 19 Jul 2006 07:40:06 GMT
ETag: "8c55da8d6abc61:2327"
就是有关页面的缓存信息的。然后如果服务器返回的响应代码不是HTTP 200 (OK),而是 304的话,浏览器就会从缓存中读取数据。
//告诉客户端浏览器不使用缓存,HTTP 1.1 协议 
header("Cache-Control: no-cache, must-revalidate"); 

//告诉客户端浏览器不使用缓存,兼容HTTP 1.0 协议 
header("Pragma: no-cache"); 
根据这个原理,可以用在不经常更新或者需要经常刷新的页面,可以大大减轻服务器的负担,因为它如果发现客户端有缓存,就向客户端发送一个304响应,然后停止程序的执行。

浏览器发出的请求中包含If-Modified-Since和If-None-Match 两个参数,第一个表示询问数据的最后修改时间是否是Thu,19 Jun 2008 16:24:01 GMT 然后服务器就会检查数据的最后修改时间,如果是该时间则返回状态码304(表示没有修改),此时当浏览器收到状态码是304时就不会下载数据而是从本地缓 存中调用。然而只有本地缓存中存在着该请求资源的数据时浏览器才会发送If-Modified-Since参数并且其值为上一次服务器所返回的Last- Modified的值(并不是所有的服务器都支持If-Modified-Since和If-None-Match );If-None-Match的功能也类似,它是由服务器返回的Etag的值生成的,可以是任意值,因为其作用仅仅是使服务器检查数据的修改时间然后返 回而已,只要不为none(默认值)或不为空其它的都可以。

所以我们可以在代码的最前部分设置返回给浏览的Etag为某个值,然后在这个资源被第二次请求的时候就会附带着一个If-None-Match 参 数,通过核实其值确实为所发出的Etag值时就可以指定服务器返回为304然后强行退出程序就行了,If-Modified-Since也是一样的做法这 里就只给出etag方法的php版(Last-Modified版的太常见了如设置缓存超时等等):
PHP 代码复制到剪贴板

复制代码 代码如下:

    if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com")
    {
        header('Etag:'.'zhaiyun.com',true,304);
        exit();
    }
    else {
        header('Etag:'."claymorephp.com");
    }
    你还可以稍微改一下:
    $expires=date("Ymd"); //一天后缓存过期
    if ($_SERVER["HTTP_IF_NONE_MATCH"] == $expires)
    {
        header('Etag:'.$expires,true,304);
        exit();
    }
    else {
        header('Etag:'.$expires);
    }
if ($_SERVER["HTTP_IF_NONE_MATCH"] == "claymorephp.com") { header('Etag:'.'zhaiyun.com',true,304); exit(); } else { header('Etag:'."claymorephp.com"); } 你还可以稍微改一下: $expires=date("Ymd"); //一天后缓存过期 if ($_SERVER["HTTP_IF_NONE_MATCH"] == $expires) { header('Etag:'.$expires,true,304); exit(); } else { header('Etag:'.$expires); }

另外,当GZIP和ETAG同时使用时有时会出问题,就是ETAG没有值,这个问题是普遍存在的,我暂时没有找到相关的原因,网上搜了一会,普遍的人称之为BUG。
基于以上原因,关于PHPBLOG的客户端缓存是以下来处理的(同时对HTTP_IF_NONE_MATCH和HTTP_IF_MODIFIED_SINCE进行判断):
PHP 代码复制到剪贴板

复制代码 代码如下:

      if($_SERVER['HTTP_IF_NONE_MATCH'])
        {
            if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog')
            {
                header('Etag:phpblog',true,304);//控制浏览器缓存
                $_SESSION['time_end']=microtime(true);
                exit();
            }
        }
        else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun, 02 Nov 2008 07:08:25 GMT; length=35849
        {
            $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']);
            $gmday=$array[1];
            $month_array=array(
            "Jan"=>"01",
            "Feb"=>"02",
            "Mar"=>"03",
            "Apr"=>"04",
            "May"=>"05",
            "Jun"=>"06",
            "Jul"=>"07",
            "Aug"=>"08",
            "Sep"=>"09",
            "Oct"=>"10",
            "Nov"=>"11",
            "Dec"=>"12");
            $gmmonth=$month_array[$array[2]];
            $gmyear=$array[3];
            $array=explode(':',$array[4]);
            $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear);
            if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60)
            {
                header('Etag:phpblog',true,304);//控制浏览器缓存
                $_SESSION['time_end']=microtime(true);
                exit();
            }
        }
if($_SERVER['HTTP_IF_NONE_MATCH']) { if($_SERVER['HTTP_IF_NONE_MATCH'] == 'phpblog') { header('Etag:phpblog',true,304);//控制浏览器缓存 $_SESSION['time_end']=microtime(true); exit(); } } else if($_SERVER['HTTP_IF_MODIFIED_SINCE'])//eg:Sun, 02 Nov 2008 07:08:25 GMT; length=35849 { $array=explode(' ',$_SERVER['HTTP_IF_MODIFIED_SINCE']); $gmday=$array[1]; $month_array=array( "Jan"=>"01", "Feb"=>"02", "Mar"=>"03", "Apr"=>"04", "May"=>"05", "Jun"=>"06", "Jul"=>"07", "Aug"=>"08", "Sep"=>"09", "Oct"=>"10", "Nov"=>"11", "Dec"=>"12"); $gmmonth=$month_array[$array[2]]; $gmyear=$array[3]; $array=explode(':',$array[4]); $gmtimestamp=gmmktime($array[0],$array[1],$array[2],$gmmonth,$gmday,$gmyear); if(gmmktime()-$gmtimestamp<$config_client_cache_time*60*60) { header('Etag:phpblog',true,304);//控制浏览器缓存 $_SESSION['time_end']=microtime(true); exit(); } }

缓存的HEADER是这样来发送的:
PHP 代码复制到剪贴板

复制代码 代码如下:

     $client_cache_time=$config_client_cache_time*60*60;//单位 - 秒
            header('Cache-Control: public, max-age='.$client_cache_time);
            header('Expires: '.gmdate('D, d M Y H:i:s',time()+$client_cache_time).' GMT');//设置页面缓存时间
            header('Last-Modified: '.gmdate('D, d M Y H:i:s',time()).' GMT');//返回最后修改时间
            header('Pragma: public');
            header('Etag:phpblog');//返回标识,用于标识上次的确访问过(浏览器中存在缓存)
$client_cache_time=$config_client_cache_time*60*60;//单位 - 秒 header('Cache-Control: public, max-age='.$client_cache_time); header('Expires: '.gmdate('D, d M Y H:i:s',time()+$client_cache_time).' GMT');//设置页面缓存时间 header('Last-Modified: '.gmdate('D, d M Y H:i:s',time()).' GMT');//返回最后修改时间 header('Pragma: public'); header('Etag:phpblog');//返回标识,用于标识上次的确访问过(浏览器中存在缓存)

时间: 2025-01-19 14:49:42

深入PHP与浏览器缓存的分析_php实例的相关文章

thinkphp的静态缓存用法分析_php实例

本文较为详细的分析了thinkphp的静态缓存用法.分享给大家供大家参考.具体分析如下: thinkphp里面内置了一个静态缓存功能,说静态缓存可能对我这种菜鸟而言不太好理解.其实静态缓存就是将THINKphp的某一个操作显示出来的页面生成一个HTML文件保存在设置的路径,当用户再次访问的时候,如果缓存没过期,那么这个操作将不再执行它下面的PHP程序,而是直接调用生成的HTML缓存文件.要使用静态缓存就需要在项目配置目录__APP__/Conf下面增加静态缓存规则文件 htmls.php,还需要

PHP文件缓存smarty模板应用实例分析_php实例

本文实例分析了PHP文件缓存smarty模板应用.分享给大家供大家参考,具体如下: 一.使用缓存 要开启smarty的缓存,只需将caching设为true,并指定cache_dir即可. 使用cache_lefetime指定缓存生存时间,单位为秒 要对相同页面生成多个不同的缓存,在display或fetch中加入第二参数cache_id,如: $smarty->display('index.tpl',$my_cache_id); 此特性可用于对不同的$_GET进行不同的缓存  二.清除缓存 c

PHP下利用header()函数设置浏览器缓存的代码_php技巧

这涉及到4种头标类型: Last-Modified(最后修改时间); Expires(有效期限); Pragma(编译指示): Cache-Control(缓存控制); 前三个头标属于HTTP1.0标准.头标Last-Modified使用UTC日期时间值.如果缓存系统发现Last-Modified值比页面缓存版本的更接 近当前时间,他就知道应该使用来自服务器的新版本. Expires 表明了缓存版本何时应该过期(格林威治标准时间).把它设置为一个以前的时间就会强制使用服务器上的页面. Pragm

ThinkPHP中数据操作案例分析_php实例

本文实例分析了ThinkPHP中数据操作方法.分享给大家供大家参考.具体如下: 模板中使用函数,相信大部分的TPer都知道也用过吧. 案例: 获取用户名的方法 function get_username($uid){ $row = M('User')->getbyUid($uid); return $row['username']; } 在模板中通过uid显示用户名 <volist name="rows" id="row"> <tr>

屏蔽浏览器缓存另类方法_php基础

有时候我们不希望浏览器使用缓存加快网页的显示,尤其是那些论坛之类的频繁更新内容的网页,在网上有说可以使用下面的方法来屏蔽缓存,但是我试了效果不好.   <META HTTP-EQUIV="Pragma" CONTENT="no-cache">   某日我突发奇想,找到了一种在任何情况下都会显示最新的网页内容的方法,描述如下:   请将网页的链接改为:   http://xxx.yyy.zzz/page.php?rand=XXXXXXX   其中http:

smarty缓存用法分析_php技巧

本文详细分析了smarty缓存的用法.分享给大家供大家参考.具体分析如下: 一开始以为smarty只是用来做一些掩饰php代码功能,但是后来才知道还有模板缓存这个强大的功能. 什么是模板缓存呢,就是我们在从数据库里面取出一些数据输出到模板的访问的时候,每一次都对数据库进行访问,但是其实每一次的数据库访问都是相同的,假如网址的流量很大,这种重复的访问完全是没有必要的,对于数据库有很大压力.smarty就提供了缓存技术,用于解决这个问题. 首先使用smarty的缓存,我们有一些要设置的: 开启缓存

Smarty高级应用之缓存操作技巧分析_php实例

本文实例讲述了Smarty高级应用之缓存操作技巧.分享给大家供大家参考,具体如下: smarty缓存控制 smarty提供了强大的缓存功能.但有时我们并不希望整篇文档都被缓存,而是有选择的缓存某一部分内容或某一部分内容不被缓存.例如你在页面上端使用一个带有广告条位置的模板,广告条可以包含任何HTML.图象.FLASH等混合信息. 因此这里不能使用一个静态的链接,同时我们也不希望该广告条被缓存. 这就需要在 insert 函数指定,同时需要一个函数取广告条的内容信息.smarty也提供了这种缓存控

Laravel Memcached缓存驱动的配置与应用方法分析_php实例

本文实例讲述了Laravel Memcached缓存驱动的配置与应用方法.分享给大家供大家参考,具体如下: Memcached缓存配置在任何php环境下我们都可以配置使用来提升WEB的性能.对于大型网站(数据多,访问量大)而言,缓存系统是必备组件,其为减轻数据库负载.提高页面访问速度.提升系统性能立下汗马功劳.Laravel作为一个功能完善且强大的PHP框架,自然为缓存系统提供了支持.目前Laravle支持的缓存驱动包括文件.数组.数据库.APC.Memcached和Redis,并且为这些驱动提

PHP爬虫之百万级别知乎用户数据爬取与分析_php实例

这次抓取了110万的用户数据,数据分析结果如下: 开发前的准备 安装Linux系统(Ubuntu14.04),在VMWare虚拟机下安装一个Ubuntu: 安装PHP5.6或以上版本: 安装MySQL5.5或以上版本: 安装curl.pcntl扩展. 使用PHP的curl扩展抓取页面数据 PHP的curl扩展是PHP支持的允许你与各种服务器使用各种类型的协议进行连接和通信的库. 本程序是抓取知乎的用户数据,要能访问用户个人页面,需要用户登录后的才能访问.当我们在浏览器的页面中点击一个用户头像链接