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 相关文章推荐
php include,include_once,require,require_once
Sep 05 PHP
php 遍历显示文件夹下所有目录、所有文件的函数,没有分页的代码
Nov 14 PHP
PHP mail 通过Windows的SMTP发送邮件失败的解决方案
May 27 PHP
php 传值赋值与引用赋值的区别
Dec 29 PHP
php $_SERVER windows系统与linux系统下的区别说明
Feb 14 PHP
thinkphp使用literal防止模板标签被解析的方法
Nov 22 PHP
smarty内置函数config_load用法实例
Jan 22 PHP
php绘制一个矩形的方法
Jan 24 PHP
Yii2中简单的场景使用介绍
Jun 02 PHP
Yii 访问 Gii(脚手架)时出现 403 错误
Jun 06 PHP
浅谈laravel5.5 belongsToMany自身的正确用法
Oct 17 PHP
laravel添加角色和模糊搜索功能的实现代码
Jun 22 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
用IE远程创建Mysql数据库的简易程序
2006/10/09 PHP
CI框架数据库查询缓存优化的方法
2016/11/21 PHP
PHP时间类完整代码实例
2021/02/26 PHP
JS高级笔记
2011/07/13 Javascript
JavaScript简单实现弹出拖拽窗口(一)
2016/06/17 Javascript
浅谈JavaScript中的this指针和引用知识
2016/08/05 Javascript
BootStrap实现响应式布局导航栏折叠隐藏效果(在小屏幕、手机屏幕浏览时自动折叠隐藏)
2016/11/30 Javascript
Javascript中JSON数据分组优化实践及JS操作JSON总结
2017/12/22 Javascript
原生JS实现的多个彩色小球跟随鼠标移动动画效果示例
2018/02/01 Javascript
基于vue.js中事件修饰符.self的用法(详解)
2018/02/23 Javascript
JavaScript+HTML5 canvas实现放大镜效果完整示例
2019/05/15 Javascript
使用异步controller与jQuery实现卷帘式分页
2019/06/18 jQuery
jquery图片预览插件实现方法详解
2019/07/18 jQuery
JS如何实现动态添加的元素绑定事件
2019/11/12 Javascript
vue项目或网页上实现文字转换成语音播放功能
2020/06/09 Javascript
[01:02:17]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG
2014/05/26 DOTA
[01:05]DOTA2完美大师赛趣味视频之选手教你打职业
2017/11/23 DOTA
PyQt5每天必学之拖放事件
2020/08/27 Python
django初始化数据库的实例
2018/05/27 Python
python numpy和list查询其中某个数的个数及定位方法
2018/06/27 Python
Python爬虫之网页图片抓取的方法
2018/07/16 Python
pycharm中显示CSS提示的知识点总结
2019/07/29 Python
Django xadmin开启搜索功能的实现
2019/11/15 Python
Python + Requests + Unittest接口自动化测试实例分析
2019/12/12 Python
关于初始种子自动选取的区域生长实例(python+opencv)
2020/01/16 Python
python实现超级玛丽游戏
2020/03/18 Python
英国Boots旗下太阳镜网站:Boots Designer Sunglasses
2018/07/07 全球购物
铣床操作工岗位职责
2014/06/13 职场文书
国庆节活动总结
2014/08/26 职场文书
群众路线教育实践活动民主生活会个人检查对照思想汇报
2014/10/04 职场文书
2015年教师党员自我评价材料
2015/03/04 职场文书
2015年教务工作总结
2015/05/23 职场文书
2015大学迎新标语
2015/07/16 职场文书
Spring Boot 启动、停止、重启、状态脚本
2021/06/26 Java/Android
windows系统搭建WEB服务器详细教程
2022/08/05 Servers
go goth封装第三方认证库示例详解
2022/08/14 Golang