PHP缓冲区用法总结


Posted in PHP onFebruary 14, 2016

本文实例总结了PHP缓冲区用法。分享给大家供大家参考,具体如下:

我们先来看一段代码。

<?php
for ($i=10; $i>0; $i--)
{
  echo $i;
  flush();
  sleep(1);
}
?>

按照php手册里的说法:

该函数将当前为止程序的所有输出发送到用户的浏览器。

上面的这段代码,应该隔一秒钟输出一次$i。但是实际中却不一定是这样。有可能是等了10秒钟后,所有的输出同时呈现出来。

好,我们来改一下这段代码,改成

<?php
ob_end_clean();//修改部分
for ($i=10; $i>0; $i--)
{
  echo $i;
  flush();
  sleep(1);
}
?>

嘿,加了这一句ob_end_clean();,居然就OK了。实际上,我们把ob_end_clean()换成ob_end_flush()也一样OK。

我再来改一改。

<?php
for ($i=10; $i>0; $i--)
{
  echo $i;
  ob_flush();//修改部分
  flush();
  sleep(1);
}
?>

运行一下,是不是发现$i也隔一秒输出一次了?这是为什么呢?
别急,我们来看看php.ini。

打开php.ini,搜索output_buffering,我们会看到类似这样的设置 output_buffering = 4096。正如它的名字output_buffering一样,这个设置的作用就是把输出缓冲一下,缓冲大小为4096bytes.

在我们的第一段代码里,之所以没有按预期的输出,正是因为这个output_buffering把那些输出都缓冲了。没达到4096bytes或者脚本结束,输出是不会被发送出去的。

而第二段代码中的ob_end_clean()和ob_end_flush()的作用,就是终止缓冲。这样就不用等到有4096bytes的缓冲之后才被发送出去了。

第三段代码中,用了一句ob_flush(),它的作用就是把缓冲的数据发送出去,但是并不会终止缓冲,所以它必须在每次flush()前使用。

如果不想使用ob_end_clean(),ob_end_flush()和ob_flush(),我们就必须把php.ini里的output_buffering设得足够小,例如设为0。需要注意的是,如果你打算在脚本中使用ini_set("output_buffering","0″)来设置,那么请停下来吧,这种方法是不行的。因为在脚本一开始的时候,缓冲设置就已经被载入,然后缓冲就开始了。

可能你会问了,既然ob_flush()是把缓冲的数据发送出去,那么为什么还需要用flush()???直接用下面这段代码不行吗??

<?php
for ($i=10; $i>0; $i--)
{
  echo $i;
  ob_flush();
  sleep(1);
}
?>

请注意ob_flush()和flush()的区别。前者是把数据从PHP的缓冲中释放出来,后者是把不在缓冲中的或者说是被释放出来的数据发送到浏览器。所以当缓冲存在的时候,我们必须ob_flush()和flush()同时使用。

那是不是flush()在这里就是不可缺少的呢?不是的,我们还有另外一种方法,使得当有数据输出的时候,马上被发送到浏览器。下面这两段代码就是不需要使用flush()了。(当你把output_buffering设为0的时候,连ob_flush()和ob_end_clean()都不需要了)

<?php
ob_implicit_flush(true);
for ($i=10; $i>0; $i--)
{
  echo $i;
  ob_flush(); #如果ob函数打开的情况下
  sleep(1);
}
?>
<?php
ob_end_clean();
ob_implicit_flush(true);
for ($i=10; $i>0; $i--)
{
  echo $i;
  sleep(1);
}
?>

请注意看上面的ob_implicit_flush(true),这个函数强制每当有输出的时候,即刻把输出发送到浏览器。这样就不需要每次输出(echo)后,都用flush()来发送到浏览器了。

以上所诉可能在某些浏览器中不成立。因为浏览器也有自己的规则。我是用Firefox1.5,IE6,opera8.5来测试的。其中opera就不能正常输出,因为它有一个规则,就是不遇到一个HTML标签,就绝对不输出,除非到脚本结束。而FireFox和IE还算比较正常的。

最后附上一段非常有趣的代码,作者为PuTTYshell。在一个脚本周期里,每次输出,都会把前一次的输出覆盖掉。
以下代码只在firefox下可用,其他浏览器并不支持multipart/x-mixed-replace的Content-Type.

<?php
 header('Content-type: multipart/x-mixed-replace;boundary=endofsection');
 print "\n--endofsection\n";
 $pmt = array("-", "\\", "|", "/" );
 for( $i = 0; $i <10; $i ++ ){
   sleep(1);
   print "Content-type: text/plain\n\n";
   print "Part $i\t".$pmt[$i % 4];
   print "--endofsection\n";
   ob_flush();
   flush();
 }
 print "Content-type: text/plain\n\n";
 print "The end\n";
 print "--endofsection--\n";
?>

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP4中session登录页面的应用
Jul 25 PHP
php daodb插入、更新与删除数据
Mar 19 PHP
php的POSIX 函数以及进程测试的深入分析
Jun 03 PHP
服务器变量 $_SERVER 的深入解析
Jul 02 PHP
php多功能图片处理类分享(php图片缩放类)
Mar 14 PHP
PHP资源管理框架Assetic简介
Jun 12 PHP
destoon二次开发入门示例
Jun 20 PHP
php格式化json函数示例代码
May 12 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
Sep 11 PHP
php中的单引号、双引号和转义字符详解
Feb 16 PHP
使用YII2框架实现微信公众号中表单提交功能
Sep 04 PHP
php基于Redis消息队列实现的消息推送的方法
Nov 28 PHP
PHP二维数组排序简单实现方法
Feb 14 #PHP
php的闭包(Closure)匿名函数初探
Feb 14 #PHP
PHP5.3新特性小结
Feb 14 #PHP
PHP解压tar.gz格式文件的方法
Feb 14 #PHP
最新版本PHP 7 vs HHVM 多角度比较
Feb 14 #PHP
PHP使用socket发送HTTP请求的方法
Feb 14 #PHP
PHP闭包函数详解
Feb 13 #PHP
You might like
php简单操作mysql数据库的类
2015/04/16 PHP
将PHP的session数据存储到数据库中的代码实例
2016/06/24 PHP
设定php简写功能的方法
2019/11/28 PHP
基于jQuery判断两个元素是否有重叠部分的代码
2012/07/25 Javascript
JQuery.Ajax之错误调试帮助信息介绍
2013/07/04 Javascript
JSON+HTML实现国家省市联动选择效果
2014/05/18 Javascript
Node调试工具JSHint的安装及配置教程
2014/05/27 Javascript
图片放大镜jquery.jqzoom.js使用实例附放大镜图标
2014/06/19 Javascript
用js提交表单解决一个页面有多个提交按钮的问题
2014/09/01 Javascript
jquery带有索引按钮且自动轮播切换特效代码分享
2015/09/15 Javascript
JavaScript截取、切割字符串的技巧
2016/01/07 Javascript
Json解析的方法小结
2016/06/22 Javascript
WEB开发之注册页面验证码倒计时代码的实现
2016/12/15 Javascript
jQuery开源组件BootstrapValidator使用详解
2017/06/29 jQuery
Bootstrap弹出框之自定义悬停框标题、内容和样式示例代码
2017/07/11 Javascript
微信小程序左滑动显示菜单功能的实现
2018/06/14 Javascript
js实现敏感词过滤算法及实现逻辑
2018/07/24 Javascript
解决vue v-for 遍历循环时key值报错的问题
2018/09/06 Javascript
微信小程序学习笔记之函数定义、页面渲染图文详解
2019/03/28 Javascript
[01:07:22]2014 DOTA2华西杯精英邀请赛 5 24 DK VS VG加赛
2014/05/26 DOTA
[54:47]Liquid vs VP Supermajor决赛 BO 第五场 6.10
2018/07/05 DOTA
[40:03]RNG vs VG 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/17 DOTA
Python实现正弦信号的时域波形和频谱图示例【基于matplotlib】
2018/05/04 Python
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
PyQt5+requests实现车票查询工具
2019/01/21 Python
python3.6使用tkinter实现弹跳小球游戏
2019/05/09 Python
离线状态下在jupyter notebook中使用plotly实例
2020/04/24 Python
keras的siamese(孪生网络)实现案例
2020/06/12 Python
美国存储和组织商店:The Container Store
2017/08/16 全球购物
利达恒信公司.NET笔试题面试题
2016/03/05 面试题
计算机学生的自我评价分享
2014/02/18 职场文书
公司担保书格式范文
2014/05/12 职场文书
司机岗位职责说明书
2014/07/29 职场文书
六查六看剖析材料
2014/10/06 职场文书
2015年行政部工作总结
2015/04/28 职场文书
表扬信格式模板
2015/05/05 职场文书