PHP output_buffering 你了解多少
一、我们要说一下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
PHP output_buffering 你了解多少的更多相关文章
- 【转】php缓冲 output_buffering和ob_start
原文: http://blog.csdn.net/21aspnet/article/details/7389427 php缓冲 output_buffering和ob_start buffer buf ...
- [PHP]php缓冲 output_buffering的使用详解
bufferbuffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域.通过buffer,可以使 ...
- output_buffering开启
ecshop后台出现Warning: Cannot modify header information - headers already sent by 修改完PHP.ini配置文件后,一定要重启服 ...
- php 基础代码大全(不断完善中)
下面是基础的PHP的代码,不断完善中~ //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线 ...
- php缓冲区详解
什么是缓冲区(buffer)? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题,如果有兴趣,可以在网山找下资料. 其实缓冲区最 ...
- PHP flush()与ob_flush()的区别
buffer ---- flush()buffer是一个内存地址空间,Linux系统默认大小一般为4096(1kb),即一个内存页.主要用于存储速度不同步的设备或者优先级不同的 设备之间传办理数据的区 ...
- PHP常用函数整理
推荐网址:http://php.net/manual/zh/http://www.w3cschool.cc/php/php-ref-array.html 错误报告: error_reporting(E ...
- php.ini 配置详解【转载】
[PHP]engine = On #是否启用PHP解析引擎zend.ze1_compatibility_mode = Off #是否在Last-Modified应答头中放置该PHP脚本的最后修改时 ...
- netbeans-xdebug 断点调试php
来自NetBeans官网的帮助文档: https://netbeans.org/kb/docs/php/debugging_zh_CN.html 但具体问题,我们还是要说下 准备工作 本地部署的ser ...
随机推荐
- C# 扩展方法奇思妙用高级篇六:WinForm 控件选择器
在Web开发中,jQuery提供了功能异常强大的$选择器来帮助我们获取页面上的对象.但在WinForm中,.Net似乎没有这样一个使用起来比较方便的选择器.好在我们有扩展方法,可以很方便的打造一个. ...
- Classifier4J的中文支持
Classifier4J是一个轻量级的分类工具,支持贝叶斯分类.向量空间模型.信息摘要等.然而它却不支持中文,异常信息大致如下: Exception in thread "main" ...
- thinkphp利用行为扩展实现监听器
1.在User/login函数中添加如下代码 tag('login_listener',$result); //alert('success', '恭喜,登录成功', U('xx/yy')); 去掉跳 ...
- 【转】google推出的SwipeRefreshLayout下拉刷新用法
SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一个下拉刷新组件,实现刷新效果更方便. 使用如下: 1.先下载android-support ...
- 使用jQuery-AJAX–读取获得跨域JSONP数据的示例
在项目开发中,如果在同一个域名下就不存在跨域情况,使用$.getJSON()即可实现.但是需要跨域请求其他域名下面的Json数据就需要JSONP的方式去请求,跨域写法和getJSON有差异.如下: ...
- C#操作Excel(1)Excel对象模型
Excel对象模型 (.Net Perspective) 本文主要针对在Visual Studio中使用C# 开发关于Excel的应用程序 本文的PDF下载地址:C#操作Excel2007.pdf ...
- URL路由规则实例
1.设置支持路由和写路由规则
- linux C(hello world)最大公约数和最小公倍数
# include <stdio.h> int main(void) { int x, y,temp; int r; printf("请输入两个正整数:\n"); sc ...
- HTML WEB 和HTML Agility Pack结合
现在,在不少应用场合中都希望做到数据抓取,特别是基于网页部分的抓取.其实网页抓取的过程实际上是通过编程的方法,去抓取不同网站网页后,再进行分析筛选的过程.比如,有的比较购物网站,会同时去抓取不同购物网 ...
- 源码级分析Android系统启动流程
首先看一下Android系统的体系结构,相信大家都不陌生 1.首先Bootloader引导程序启动完Linux内核后,会加载各种驱动和数据结构,当有了驱动以后,开始启动Android系统,同时会加载用 ...