缓存总结

缓存分为两种:一种是浏览器缓存;一种是服务器缓存。
下面总结一下最近学习到的关于缓存的知识以及其应用。

一、浏览器缓存

浏览器缓存,也叫客户端缓存,它能够保存用户访问过的一些网站的信息。所以浏览器才会出现“后退”的功能。而当用户后退上一个网页的时候,发现往往比第一次访问的时候快很多。这就是因为你第一次访问的时候,网页信息已经被放在了浏览器缓存中,后退的时候,直接从缓存中取的数据,所以这样当然会比从互联网中取数据快的多了。

二、WEB服务器缓存

web服务器缓存分为两种:一种是程序缓存。一种是OB缓存

首先确认一下,php.ini中output_buffering是关闭的。接下来上例子:

例子1:
1
2
3
header('Content-Type:text/html;charset=utf-8');
echo "aaa";
echo "bbb";

这三行代码的执行过程是:

  • 1、首先执行header(),程序缓存区发现没有http头信息,那么就把这个header充当头信息了。
  • 2、echo "aaa",就把”aaa”输出到程序缓存中。
  • 3、echo "bbb",就把”bbb”输出到程序缓存中。
  • 4、把http头信息以及aaabbb整体封装成一个http响应,通过apache或nginx发送给浏览器显示。
例子2:
1
2
3
echo "aaa";
header('Content-Type:text/html;charset=utf-8');
echo "bbb";

这三行代码的执行过程是:

  • 1、echo "aaa",就把”aaa”输出到程序缓存中,但是这个时候,程序缓存中发现没有http头信息,那么就会生成一个默认的http头信息。
  • 2、执行header(),把这个头信息放入程序缓存中,结果发现里面已经含有一个http头信息,所以报错啦。Cannot modify header information - headers already sent by ...

为了解决例子2中的问题。OB缓存出现了

例子3:

有两种方式能防止上面的错误。
第一种是:php.ini中开启output_buffering
第二种是通过ob_start():

1
2
3
4
ob_start();
echo "aaa";
header('Content-Type:text/html;charset=utf-8');
echo "bbb";

这两种方法的效果是一样的,开启output_buffering和ob_start()是一样的。他们的执行顺序是:

  • 1、ob缓存开启;
  • 2、把aaa放入ob缓存中;
  • 3、header(),发现程序缓存中没有http头信息,那么就把header充当http头信息。
  • 4、把bbb放入ob缓存中。
  • 5、程序结束、把ob缓存中的数据刷入程序缓存中。然后打包成http响应发送给浏览器。

根据这三个例子,我们能弄明白程序缓存与OB缓存的区别。小结:

  • 首先程序缓存是必须存在的,也就是不能关闭的。
  • http头的信息,必须存在程序缓存,而不能存在OB缓存。
  • 程序执行结束后,会把http头与内容封装成响应发送给浏览器。

现在我们想实现一个功能:依次输出1-5。每输出一个数sleep 1 秒。

例子4:
1
2
3
4
5
$i =1;
while($i<5){
echo $i++;
sleep(1);
}

这段代码的执行顺序是:

  • 1、输出1到程序缓存
  • 2、sleep 1秒
  • 3、重复上述步骤
  • 4、浏览器输出12345.

结果发现跟我们预想的结果是不一样的。这是因为程序会预先把所有结果输出到程序缓存中,等程序结束后才会把程序缓存输出到屏幕上

例子5:
1
2
3
4
5
6
$i =1;
while($i<5){
echo $i++;
flush();
sleep(1);
}

flush()这个函数会把程序缓存的内容输出到浏览器中,并且清空程序缓存区的内容。这样就可以做到1-5依次输出到屏幕,每次sleep1秒啦。

那么怎么使用ob缓存实现这么功能呢?

例子6:
1
2
3
4
5
6
7
8
9
10
11
12
13
if (ob_get_level() == 0){
ob_start();
}
while (ob_get_level() > 1){
ob_end_clean();
}
$i =1;
while($i<5){
echo $i++;
ob_flush();
flush();
sleep(1);
}
  • 1、ob_get_level是用来查询ob等级,如果是0那么就说明没有开启ob缓存。
  • 2、如果ob等级>1。就说明多次开启ob缓存,而ob缓存是嵌套的,如果开启多次。那么输出的值会存在最里面的那层ob缓存,所以需要保证ob缓存只存在1层。
  • 3、ob_end_clean()是用于把ob缓存区的数据清空,并把该ob缓存关闭。
  • 4、ob_flush是用于把ob缓存区的数据复制到程序缓存区,并清空ob缓存。
  • 4、flush程序缓存的内容输出到浏览器,并清空。

OB缓存的功能

  • 1)防止在浏览器有输出之后再使用setcookie()、header()或session_start()等发送头文件的函数造成的错误。其实这样的用法少用为好,养成良好的代码习惯。
  • 2)捕捉对一些不可获取的函数的输出,比如phpinfo()会输出一大堆的HTML,但是我们无法用一个变量例如$info=phpinfo();来捕捉,这时候ob就管用了。
  • 3)对输出的内容进行处理,例如进行gzip压缩,例如进行简繁转换,例如进行一些字符串替换。
  • 4)生成静态文件,其实就是捕捉整页的输出,然后存成文件。经常在生成HTML,或者整页缓存中使用。(特别重要
  • 5)可以写聊天工具,用户有消息就刷新显示到浏览器。

OB精髓—静态模版技术

所谓静态模版技术就是通过某种方式,使得用户在client端得到的是由PHP产生的html页面。如果这个html页面不会再被更新,那么当另外的用户再次浏览此页面时,程序将不会再调用PHP以及相关的数据库,对于某些信息量比较大的网站,例如sina、163、sohu这种门户网站。类似这种的技术带来的好处是非常巨大的。

1
2
3
4
5
6
ob_start(); //打开缓冲区
php页面的全部输出
$content = ob_get_contents(); //取得php页面输出的全部内容
$fp = fopen("output00001.html", "w"); //创建一个文件,并打开,准备写入
fwrite($fp, $content); //把php页面的内容全部写入output00001.html,然后……
fclose($fp);

资料

文章目录
  1. 1. 一、浏览器缓存
  2. 2. 二、WEB服务器缓存
    1. 2.1. web服务器缓存分为两种:一种是程序缓存。一种是OB缓存。
      1. 2.1.1. 例子1:
      2. 2.1.2. 例子2:
      3. 2.1.3. 例子3:
    2. 2.2. 根据这三个例子,我们能弄明白程序缓存与OB缓存的区别。小结:
    3. 2.3. 现在我们想实现一个功能:依次输出1-5。每输出一个数sleep 1 秒。
      1. 2.3.1. 例子4:
      2. 2.3.2. 例子5:
      3. 2.3.3. 例子6:
    4. 2.4. OB缓存的功能
    5. 2.5. OB精髓—静态模版技术
    6. 2.6. 资料
,