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

<?php

echo "南无阿弥陀佛<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) 才能调试出你想要的效果。

参考资料

深入理解ob_flush和flush的区别

--EOF--

 我不是码农,我只是互联网的搬运工。如果对你有帮助,麻烦点赞啊:-D,那是我的动力。

PHP 输出缓冲控制(Output Control) 学习的更多相关文章

  1. PHP输出缓冲控制- Output Control 函数应用详解

    说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffer写满 ...

  2. PHP输出缓冲控制 - Output Control 函 应用详解

    简介 说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会向磁盘写入的,而是写到buffer中,当buffe ...

  3. PHP输出缓冲控制

    说到输出缓冲,首先要说的是一个叫做缓冲器(buffer)的东西.举个简单的例子说明他的作用:我们在编辑一篇文档时,在我们没有保存之前,系统是不会 向磁盘写入的,而是写到buffer中,当buffer写 ...

  4. PHP中的输出缓冲控制

    在 PHP 中,我们直接进行 echo . 或者 print_r 的时候,输出的内容就会直接打印出来.但是,在某些情况下,我们并不想直接打印,这个时候就可以使用输出缓冲控制来进行输出打印的控制.当然, ...

  5. PHP输出缓冲(Output Buffering)

    什么是缓冲区? 简单而言,缓冲区的作用就是,把输入或者输出的内容先放进内存,而不显示或者读取.至于为什么要有缓冲区,这是一个很广泛的问题~其实缓冲区最本质的作用就是,协调高速CPU和相对缓慢的IO设备 ...

  6. php Output Control 函数 ob_系列函数详解

    <?php /* * 输出缓冲控制 * * flush — 刷新输出缓冲 ob_clean — 清空(擦掉)输出缓冲区 ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲 ob_en ...

  7. php 输出缓冲 Output Control

    关于php的输出缓冲,首先要说明的是什么是缓冲(buffer),比如我们通过记事本在编辑文件的时候,并不是我们输入了内容,系统就会立刻向磁盘中写入数据.只有我们在保存文件后,系统才会向磁盘写入数据.而 ...

  8. PHP输出控制(Output Control)函数

    ob_start 此函数将打开输出缓冲.当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中. 内部缓冲区的内容可以用 ob_get_contents() ...

  9. C语言学习笔记之输出缓冲

    在c语言中经常用到输出函数printf,当我们像往常一样在输出函数中输入我们的想要的输出的东西后加\n换行 验证结果如我们输出的一样 如果我们在后面加入死循环会不会出现这些语句呢 结果卡死了,可还是输 ...

随机推荐

  1. Spring Boot构建RESTful API与单元测试

    如果您对Spring MVC不熟悉并且还没有尝试过快速入门案例,建议先看一下相关的内容. @Controller:修饰class,用来创建处理http请求的对象 @RestController:Spr ...

  2. [内核]Linux workqueue

    转自:http://blog.chinaunix.net/uid-24148050-id-296982.html 一.workqueue简介workqueue与tasklet类似,都是允许内核代码请求 ...

  3. 本地和VMware虚拟主机之间的网络访问

    在需要设置的虚拟主机节点上右键,点击[设置...] 在打开的虚拟机设置中,选中[网络适配器],之后在右边设置网络连接为[自定义:指定的虚拟网络] 然后设置同一网关即可.

  4. 【转】C#环形队列

    概述 看了一个数据结构的教程,是用C++写的,可自己C#还是一个菜鸟,更别说C++了,但还是大胆尝试用C#将其中的环形队列的实现写出来,先上代码: 1 public class MyQueue< ...

  5. U盘安装ubuntu server 12.04的问题检测不到CDROM的解决

    U盘安装ubuntu server 12.04的问题检测不到CDROM的解决 ========================== 我是u盘安装ubuntu 14 64Bit 也是出现同样的问题 用u ...

  6. python 版本问题大全

    坑一 一下午的时间又让这个不是问题的问题给白白给浪费了,此片文章仅仅纪念一下浪费掉的宝贵时间 新式类与经典类问题 class qwe: def __init__(self, name): self.n ...

  7. iOS开发--应用设置及用户默认设置【1、bundle的运用】

           在iphone里面,应用都会在“设置”里面有个专属的应用设置,选择该菜单界面,用户便可以在其中输入和更改各种选项,协助用户更便捷设置个人喜好与习惯. 在这一节中,希望能通过对捆绑包(bu ...

  8. js动画性能提升笔记

    JavaScript动画的性能并不亚于CSS动画.因此,如果使用了现代的动画库,例如Velocity,那么动画引擎的性能将不再是app的瓶颈,构成瓶颈的只有代码. 网络性能相关 动画是浏览器运行中资源 ...

  9. mvc中Scripts.Render、Styles.Render

    一.配置BundleConfig.cs文件 1.首先要在App_Start 里面BundleConfig.cs 文件里面 添加要包含的css文件 2.BundleConfig就是一个微软新加的 一个打 ...

  10. nuint笔记

    注意:单元测试中,Case 与 Case 之间不能有任何关系 测试方法不能有返回值,不能有参数,测试方法必须声明为 public [TestFixture] //声明测试类 [SetUp] //建立, ...