一、我们要说一下php中的缓存大概有哪些!

在PHP中,我们可以粗略的将缓存分为客户端缓存(Browser缓存),服务器端缓存(Server缓存)。由于PHP是基于B/S架构的,所以,我们可以理解为浏览器端的缓存,服务器端缓存。
在服务器端PHP自带的缓存中,主要可以分为两大类缓存!程序缓存和OB缓存!这也是我们学习服务器端缓存的主要内容!

在PHP中缓存的输出顺序为:

打开了php输出缓存: echo,print -> php output_buffering -> server buffering -> browser buffering -> browser display

未打开php输出缓存: echo,print -> server buffering -> browser buffering -> browser display

浏览器的输出缓存:IE为256Bytes, Chrome与FireFox为1000Bytes,只有输出数据达到了这个长度或者脚本结束浏览器才会将数据输出在页面上。

二、服务器端的响应流程

A、客户端向服务器端发送请求响应!
B、Apache服务器加载了PHP模块,开启相应的进程(或线程)运行相应的PHP脚本页面!
C、在没有开启OB缓存的情况下,运行的结果全部都会被放到程序缓存中,然后打包发送给浏览器!浏览器对页面进行渲染,生成我们最后看到的WEB页面!
D、在开启了OB缓存的情况下,运行的结果会被分别放入到OB缓存和程序缓存中,当程序运行到最后一行的时候,就会将OB缓存中的数据刷回到程序缓存中,然后打包返回给浏览器!浏览器对页面进行渲染,生成我们看到的WEB页面!

三、OB缓存的常见用法!

a、output_buffering=4096,输出较少的数据(少于一个buffer)

for($i=0; $i<5; $i++){  

echo $i.'<br>';  

sleep(1);  

}

运行结果:等所有脚本全部运行完成后,才输出,因为数据未满一个buffer的大小。

b、output_buffering=4096,输出较少的数据(少于一个buffer),关闭output_buffering,修改php.ini的output_buffering=0

echo str_repeat(" ",1024);//这里重复输出一个空白

for($i=0; $i<5; $i++){  

echo $i."<br/>";

    flush();  

    sleep(1);  

} 

运行结果:因为禁用了OB,不需要等到脚本运行完毕就可以输出,数据没有在OB停留,可以看到断断续续间歇性输出。echo ->browser buffering -> browser display

c、output_buffering=4096,输出较大数据(大于一个buffer),不使用ob_start()

for($i=0; $i<5; $i++){  

    echo file_get_contents('f.txt').$i.'<br/><br/><br/><br/>';  

    sleep(2);  

} 

运行结果:f.txt为一个大于4kb的文件,因为大于buffer默认值,buffer空间不够用,每当满一个buffer就会输出,所以可以看到间歇性输出。

d、output_buffering=4096,输出较大数据(大于一个buffer),使用ob_start()

ob_start();  

for($i=0; $i<5; $i++){  

    echo file_get_contents('f.txt').$i.'<br/><br/><br/><br/>';  

    sleep(2);  

} 

运行结果:因为使用了ob_start(),会为buffer设置足够大的空间,因此会保存到脚本执行完毕后才会输出。

e、output_buffering=On,使用ob_start()

ob_start(); 

echo "abc-";

header("content-type:text/html;charset=utf-8");

echo "hello-";

ob_end_flush();

echo "aa-";

echo ob_get_contents();

运行结果:abc-hello-aa-abc-hello-aa-

f、output_buffering=Off,使用ob_start()

ob_start(); 

echo "abc-";

header("content-type:text/html;charset=utf-8");

echo "hello-";

ob_end_flush();

echo "aa-";

echo ob_get_contents();

运行结果:abc-hello-aa-

输出缓冲区是可堆叠的,这即意谓着,当有一个 ob_start() 是活跃的时, 你可以调用另一个 ob_start() 。 只要确保又正确调用了 ob_end_flush() 恰当的次数即可。 如果有多重输出回调函数是活跃的,输出内容会一直按嵌套的顺序依次通过它们而被过滤。

注意:PHP5.2中,OB默认是关闭的,5.3之后默认是开启的;

常用方法:

1.ob_start
激活output_buffering机制,一旦激活,脚本不再直接输出到浏览器,而是暂时写入php buffering区域。直到脚本运行完毕后,才发送。

2.ob_get_contents
获取php buffering中的数据,注意:要在ob_end_clean()前调用,否则只会得到空字符。

3.ob_end_flush 和 ob_end_clean
ob_end_flush 会输出php buffering 中的数据,但不会清空。
ob_end_clean 不会输出,只会清空php buffering中的数据。

4.ob_flush 、flush、ob_implicit_flush
ob_flush 会刷新php buffering 中的数据到程序缓存

flush 则会刷新程序缓存到浏览器缓存中

ob_implicit_flush 将打开或关闭绝对(隐式)刷送。绝对(隐式)刷送将导致在每次输出调用后有一次刷送操作,以便不再需要对 flush() 的显式调用

四、OB缓存的作用!

OB缓存在各个方面都有应用,但是,本人知道的主要是在两个方面!
a、当网站准备做网站静态化的时候,选择OB缓存是一个不错的选择!

b、解决Warning: Cannot modify header information - headers already sent by的错误!
究其发生错误的原因:是因为响应头和相应主体位置错位导致的!正常情况下,服务器返回给浏览器的相应内容,应该是:响应头+响应主体!
但是,如果我们开启了OB缓存,那么相应头信息(一般也就是header()函数进行设置的信息),会被放入到程序缓存中!
而其他的输出内容,如:echo print_r var_dump 等,都会先被放入OB缓存中!
等程序结束的时候,或者OB缓存关闭的实话,将OB缓存的内容在放入程序缓存中!从而保证响应头信息,始终在响应主体内容之前!

五、参考资料:

http://segmentfault.com/a/1190000000578885

http://blog.csdn.net/fdipzone/article/details/10367837

http://php.net

PHP output_buffering 你了解多少的更多相关文章

  1. 【转】php缓冲 output_buffering和ob_start

    原文: http://blog.csdn.net/21aspnet/article/details/7389427 php缓冲 output_buffering和ob_start buffer buf ...

  2. [PHP]php缓冲 output_buffering的使用详解

    bufferbuffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域.通过buffer,可以使 ...

  3. output_buffering开启

    ecshop后台出现Warning: Cannot modify header information - headers already sent by 修改完PHP.ini配置文件后,一定要重启服 ...

  4. php 基础代码大全(不断完善中)

    下面是基础的PHP的代码,不断完善中~ //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线 ...

  5. php缓冲区详解

    什么是缓冲区(buffer)? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料. 其实缓冲区最 ...

  6. PHP flush()与ob_flush()的区别

    buffer ---- flush()buffer是一个内存地址空间,Linux系统默认大小一般为4096(1kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的 设备之间传办理数据的区 ...

  7. PHP常用函数整理

    推荐网址:http://php.net/manual/zh/http://www.w3cschool.cc/php/php-ref-array.html 错误报告: error_reporting(E ...

  8. php.ini 配置详解【转载】

    [PHP]engine = On   #是否启用PHP解析引擎zend.ze1_compatibility_mode = Off #是否在Last-Modified应答头中放置该PHP脚本的最后修改时 ...

  9. netbeans-xdebug 断点调试php

    来自NetBeans官网的帮助文档: https://netbeans.org/kb/docs/php/debugging_zh_CN.html 但具体问题,我们还是要说下 准备工作 本地部署的ser ...

随机推荐

  1. HDU 5444 Elven Postman (二叉树,暴力搜索)

    题意:给出一颗二叉树的先序遍历,默认的中序遍历是1..2.……n.给出q个询问,询问从根节点出发到某个点的路径. 析:本来以为是要建树的,一想,原来不用,其实它给的数是按顺序给的,只要搜结点就行,从根 ...

  2. C# JackLib系列之Form窗体的ShowWithoutActivation属性及其作用

    代码改变世界! 如果要显示顶级窗口,但又不希望由于将输入焦点从当前窗口移开而中断用户的工作,请使用此属性.它可以是一个信息性弹出窗口或浮动窗口,如“画图”应用程序中的“工具”调色板. 由于此属性为只读 ...

  3. INVALID_SOCKET的值

    INVALID_SOCKET的值 (2011-06-26 15:06:45) 标签: 杂谈 INVALID_SOCKET的值不是-1,原因参考basetsd.h和WinSock2.h: typedef ...

  4. Java图片处理(一)图片合成

    如何将多个头像合成类似QQ的群头像? 如上图所示,如何用java将单一的图片合成如上群头像. 在一个正方形外框中,要将多个图片合成上述图片.首先要做的是,依据圆相交的程度,计算圆心坐标与图片间空白区域 ...

  5. 关于App.config配置文件

    今天在做复习的时候,突然发现自己无法读取配置文件中的数据库连接字符串,而且检查了半天也没找出原因,最后求助万能的度娘才得以解决—— 1.App.config配置文件在项目中添加后不要修改名称,否则会出 ...

  6. php获取GET方式传入的全部变量名称与值:foreach用法

    $count = count($_GET); $i = 0; foreach ($_GET as $key => $value) { if ($i == $count - 1) { $str . ...

  7. OpenGL光照测试

    OpenGL光照测试 花了大概半个月,研究了OpenGL的光照.请注意是固定管线渲染的光照,如果使用着色器的高手们请飘过.这个程序是通过光照对模型的照射,来研究OpenGL光照的性质.以后可以通过这个 ...

  8. PostgreSQL中使用枚举类型

    https://wiki.postgresql.org/wiki/Enum 建立enum: pgsql=# CREATE TYPE mood AS ENUM ('sad', 'ok', 'happy' ...

  9. 关闭IE窗口

    $a=(New-Object -comObject Shell.Application).Windows() ($a|?{$_.locationname -eq "人力与人才信息管理系统&q ...

  10. Codeforces Gym 100531J Joy of Flight 变换坐标系

    Joy of Flight 题目连接: http://codeforces.com/gym/100531/attachments Description Jacob likes to play wit ...