PHP flush的区别详解_php实例_脚本之家

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中的脏数据写回磁盘。

buffer —-
flush()
buffer是一个内存地址空间,Linux系统默认大小一般为4096,即一个内存页。主要用于存储速度不同步的设备或者优先级不同的
设备之间传办理数据的区域。通过buffer,可以使进程这间的相互等待变少。这里说一个通俗一点的例子,你打开文本编辑器编辑一个文件的时候,你每输入
一个字符,操作系统并不会立即把这个字符直接写入到磁盘,而是先写入到buffer,当写满了一个buffer的时候,才会把buffer中的数据写入磁
盘,当然当调用内核函数flush()的时候,强制要求把buffer中的脏数据写回磁盘。同样的道理,当执行echo,print的时候,输出并没有立即通过tcp传给客户端浏览器显示,
而是将数据写入php buffer。php output_buffering机制,意味在tcp
buffer之前,建立了一新的队列,数据必须经过该队列。当一个php
buffer写满的时候,脚本进程会将php
buffer中的输出数据交给系统内核交由tcp传给浏览器显示。所以,数据会依次写到这几个地方echo/pring
-> php buffer -> tcp buffer -> browserphp output_buffering
— ob_flush()
默认情况下,php
buffer是开启的,而且该buffer默认值是4096,即1kb。你可以通过在php.ini配置文件中找到output_buffering配置.当echo,print等输出用户数据的时候,输出数据都会写入到php
output_buffering中,直到output_澳门新葡亰赌995577,buffering写满,会将这些数据通过tcp传送给浏览器显示。你也可以通过
ob_start()手动激活php
output_buffering机制,使得即便输出超过了1kb数据,也不真的把数据交给tcp传给浏览器,因为ob_start()将php
buffer空间设置到了足够大
。只有直到脚本结束,或者调用ob_end_flush函数,才会把数据发送给客户端浏览器。

举个例子

<?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:phptest.php:3)
//真善忍好

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

这两个函数的使用怕是很多人最迷惑的一个问题,手册上对两个函数的解释也语焉不详,没有明确的指出它们的区别,似乎二者的功能都是刷新输出缓存。但在我们文章一开始的代码中如果讲fush,程序就再不能正确执行了。显然,它们是有区别的,否则也手册中直接说明其中一个是另外一个函数的别名即可了,没必要分别说明。那么它们的区别到底是什么呢?在没有开启缓存时,脚本输出的内容都在服务器端处于等待输出的状态
,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个字符。

开启缓存后,脚本输出的内容存入了输出缓存中
,这时没有处于等待输出状态的内容,你直接使用flush()不会向客户端发出任何内容。而
ob_flush()的作用就是将本来存在输出缓存中的内容取出来,设置为等待输出状态,但不会直接发送到客户端
,这时你就需要先使用 ob_flush,客户端才能立即获得脚本的输出。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

相关文章

网站地图xml地图