PHP 输出缓冲控制(Output Control)详解


Posted in PHP onAugust 25, 2016

  php 缓冲简介

      其实我对php ob 系列印象还是很模糊,具体怎么玩的,还不是很了解,平时curd,确实对这些内容没有深入。作为phper 甚是惭愧。网上搜了一通,互相copy,代码运行不能出现作者所描述现象,本文良心出品,代码都是作者运行过。

 

当执行输出的时候,比如 echo,print。输出并没有立即送给 web server, 而是将数据写入 php buffer。php output_buffering 机制好处当然提升性能。其实 php 文件最终在浏览器上显示,走过3个缓冲阶段: php buffer=》web server buffer=》browser buffer。 最后显示到浏览器

默认情况下,php buffer 是开启的,而且该 buffer 默认值是4096,即4 kb。你可以通过在php.ini配置文件中找到output_buffering配置。buffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页。主要用于存储速度不同步的设备或者优先级不同的设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。

  举个例子

<?php
echo "南无阿弥陀佛<br>";
header("content-type:text/html;charset='utf-8'");
echo "真善忍好!";
//output
//南无阿弥陀佛
//真善忍好

header()必须在任何实际输出之前调用,但是我们程序已经输出了,却正常运行。在看下面的代码:

<?phpecho "南无阿弥陀佛<br>";
ob_flush();
header("content-type:text/html;charset='utf-8'");
echo "真善忍好!";
//output
//南无阿弥陀佛
//Cannot modify header information - headers already sent by (output started at E:\php\test.php:3)
//真善忍好

上面程序说明程序并没有立即输出,而当调用ob_flush 函数的时候才刷新缓冲,输出。

  ob_flush() 与 flush()

ob_flush() , flush() 函数php 手册上都有详细的说明,你可以去查阅一下。二者的区别是:

ob_flush() 是刷新PHP自身的缓冲区

flush()是 它是刷新WebServer 服务器的缓冲。输出到浏览器。但是会出现下面的情况:

  1. 个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。
  2. 有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。
  3. 甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 </table> 标记之前,不会显示出整个表格。
  4. 一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。

 比如:

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo '佛法无边'."<BR>";
ob_flush();
flush();
sleep(1);
echo '法轮常转';

//output

上面的代码 在 chrome 浏览器上面 是一行一行的输出,在ie系列的浏览器则是全部输出。其实就是上面的 第四条一些浏览器只有当接收256个字符才开始显示。把上面的代码改成下面形式:

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo str_pad('',240)."\n"; 
echo '佛法无边'."<BR>";
ob_flush();
flush();
sleep(1);
echo '法轮常转';

//output

这样在ie下面就会一行一行输出,因为超过256个字符。

  ob 其他函数说明

1.ob_end_flush 与 ob_end_clean

end 的顾名思义就结束,关闭缓冲区,都是关闭输出缓冲,一个是输出缓冲区,一个是清除。比如

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo 'before';
ob_end_clean();
echo str_pad('',4096)."\n";
for ($i=10; $i>0; $i--) 
{ 
 echo $i;
 sleep(1);
}

上述代码是一下输出全部内容,而不是一个一个输出。ob_end_clean() 不是关闭了缓冲了?怎么不是一个一个输出呢,其实我们上面也说了,php 不是直接输出给浏览器,而是 web server。 虽然php 没有了 缓冲。但是web server 还是有的。所以下面代码:

/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo 'before';
ob_end_clean();
echo str_pad('',4096)."\n";
for ($i=10; $i>0; $i--) 
{ 
 flush();
 echo $i;
 sleep(1);
}

加上flush(),就会一行一行输出。 如果把ob_end_clean 换成 ob_end_flush  会把 before 输出来。

其他函数 可参考手册,比较简单。

  总结

php 脚本到浏览器,要经过  php buffer=》web server buffer=》browser buffer。 最后显示到浏览器。 缺一不可。 所以我们要 ob_flush 和  flush 以及加上  echo str_pad('',4096) 才能调试出你想要的效果。

以上就是对PHP 缓冲的资料整理后续继续补充相关资料,谢谢大家对本站的支持!

PHP 相关文章推荐
教你如何把一篇文章按要求分段
Oct 09 PHP
PHP表单验证的3个函数ISSET()、empty()、is_numeric()的使用方法
Aug 22 PHP
php 批量替换程序的具体实现代码
Oct 04 PHP
PHP开源开发框架ZendFramework使用中常见问题说明及解决方案
Jun 12 PHP
php 无限级分类,超级简单的无限级分类,支持输出树状图
Jun 29 PHP
Yii框架调试心得--在页面输出执行sql语句
Dec 25 PHP
jquery+php实现导出datatables插件数据到excel的方法
Jul 06 PHP
PHP获取input输入框中的值去数据库比较显示出来
Nov 16 PHP
zend框架实现支持sql server的操作方法
Dec 08 PHP
PHP实现的mysql主从数据库状态检测功能示例
Jul 20 PHP
php 实现简单的登录功能示例【基于thinkPHP框架】
Dec 02 PHP
tp5.1 框架join方法用法实例分析
May 26 PHP
PHP中利用sleep函数实现定时执行功能实现代码
Aug 25 #PHP
PHP sleep()函数, usleep()函数
Aug 25 #PHP
PHP页面间传递值和保持值的方法
Aug 24 #PHP
PHP中explode函数和split函数的区别小结
Aug 24 #PHP
php处理单文件、多文件上传代码分享
Aug 24 #PHP
PHP简单创建压缩图的方法
Aug 24 #PHP
php利用header函数下载各种文件
Aug 24 #PHP
You might like
php报表之jpgraph柱状图实例代码
2011/08/22 PHP
PHP转换文件夹下所有文件编码的实现代码
2013/06/06 PHP
PHP Try-catch 语句使用技巧
2016/02/28 PHP
PHP 爬取网页的主要方法
2018/07/13 PHP
Laravel获取当前请求的控制器和方法以及中间件的例子
2019/10/11 PHP
JavaScript XML实现两级级联下拉列表
2008/11/10 Javascript
js取滚动条的尺寸的函数代码
2011/11/30 Javascript
浅谈javascript的原型继承
2012/07/25 Javascript
JQuery加载图片自适应固定大小的DIV
2013/09/12 Javascript
Javascript 按位与赋值运算符 (&amp;=)使用介绍
2014/02/04 Javascript
node.js中的socket.io的广播消息
2014/12/15 Javascript
快速解决Canvas.toDataURL 图片跨域的问题
2016/05/10 Javascript
jquery UI Datepicker时间控件冲突问题解决
2016/12/16 Javascript
微信小程序 详解Page中data数据操作和函数调用
2017/01/12 Javascript
微信小程序 利用css实现遮罩效果实例详解
2017/01/21 Javascript
jQuery插件autocomplete使用详解
2017/02/04 Javascript
Angular4实现鼠标悬停3d倾斜效果
2017/10/25 Javascript
vue2.0实现音乐/视频播放进度条组件
2018/06/06 Javascript
微信小程序自定义组件components(代码详解)
2019/10/21 Javascript
详解vue-flickity的fullScreen功能实现
2020/04/07 Javascript
微信小程序实现签到弹窗动画
2020/09/21 Javascript
node koa2 ssr项目搭建的方法步骤
2020/12/11 Javascript
python脚本爬取字体文件的实现方法
2017/04/29 Python
Python PyQt5实现的简易计算器功能示例
2017/08/23 Python
django rest framework 实现用户登录认证详解
2019/07/29 Python
对YOLOv3模型调用时候的python接口详解
2019/08/26 Python
Python socket 套接字实现通信详解
2019/08/27 Python
利用matplotlib实现根据实时数据动态更新图形
2019/12/13 Python
python实现扫雷小游戏
2020/04/24 Python
pycharm全局搜索的具体步骤
2020/07/28 Python
CSS3教程(6):创建网站多列
2009/04/02 HTML / CSS
HTML5 video进入全屏和退出全屏的实现方法
2020/07/28 HTML / CSS
Snapfish爱尔兰:在线照片打印和个性化照片礼品
2018/09/17 全球购物
俄罗斯购买剧院和演唱会门票网站:Parter.ru
2019/11/09 全球购物
serialVersionUID具有什么样的特征
2014/02/20 面试题
什么是规则表达式
2012/05/03 面试题