当前位置: 代码迷 >> 综合 >> phpnbsp;ob_start()、ob_end_flus…
  详细解决方案

phpnbsp;ob_start()、ob_end_flus…

热度:69   发布时间:2024-01-18 11:33:05.0

 ob_start() 和 ob_end_flush() 是一对很好的搭档,可以实现对输出的控制。当成一对出现理解起来就没什么问题,但是当他们两个各自出现次数增加时,就比较难理解了.

01

02
ob_start();
03
echo 'level 1
';
04
ob_start();
05
echo   'level 2
';
06
ob_start();
07
echo  'level 3
';
08
ob_end_flush();
09
ob_end_flush();
10
ob_end_flush();
很明显,结果为:
level 1
level 2
level 3

当程序修改一下,修改一个ob_end_flush() 变成 ob_end_clean() 成为以下这个,你觉得结果会是怎样呢?附上这几个函数的讲解:

ob_clean — 清空(擦掉)输出缓冲区
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
ob_flush — 冲刷出(送出)输出缓冲区中的内容
ob_start — 打开输出控制缓冲
01

02
ob_start();
03
echo   'level 1
';
04
ob_start();
05
echo   'level 2
';
06
ob_start();
07
echo   'level 3
';
08
ob_end_clean();//修改处
09
ob_end_flush();
10
ob_end_flush();
结果:
level 1
level 2

可能你会认为ob_end_clean()会清除与他最近的ob_start()的输出;其实这个说法不是很全面,看下面的例子

01

02
ob_start();
03
echo   'level 1
';
04
ob_start();
05
echo   'level 2
';
06
ob_start();
07
echo   'level 3
';
08
ob_end_clean(); //第一次修改
09
ob_end_flush();
10
ob_end_clean(); //第二次修改
这次,什么都没有输出来。
中间不是有一个ob_flush()吗?按理来说应该是输出  level2 的。

其实造成这样的主要原因是输出的多级缓冲机制。这个程序例子有三个ob_start(),就意味着他有3个缓冲区A,B,C,而其实php程序本身也有一个最终输出的缓冲区,我们就把他叫做F。

在这个程序中他这几个缓冲区是有一定层次的,C->B->A->F,F层次最高,是程序最终的输出缓冲,我们按上面的程序来进行讲解。

 

刚开始。  F:null

1
ob_start();
 新建缓冲区A。  A: null -> F:null

1
echo   'level 1
';
程序有输出,输出进入最低的缓冲区A  A: 'level 1
' -> F:null

1
 ob_start();
新建缓冲区B 。 B:null  ->  A: 'level 1
' -> F:null

1
echo   'level 2
';
程序有输出,输出进入最低的缓冲区B     B:'level 2
' ->  A: 'level 1
' ->F:null

1
ob_start();
新建缓冲区C   C:null  B:'level 2
  A: 'level 1
' -> F:null

1
echo   'level 3
';
程序有输出,输出进入最低的缓冲区C    C:'level 3
->  B:'level 2
->  A: 'level 1
' -> F:null

1
ob_end_clean(); //第一次修改
缓冲区C被清空并关闭。  B:'level 2
->  A: 'level 1
' -> F:null

1
ob_end_flush();
缓冲区B输出到上一级的缓冲区A并关闭。   A: 'level 1
level 2
' -> F:null

1
ob_end_clean(); //第二次修改
 缓冲区A被清空并关闭。 此时缓冲区A的东西还没真正输出到最终的F中,因此也就整个程序也就没有任何的输出了。

 ob其他的函数还有很多,但只要能懂得这些机理应该也是不难懂的。附上其余函数

flush — 刷新输出缓冲
ob_clean — 清空(擦掉)输出缓冲区
ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
ob_flush — 冲刷出(送出)输出缓冲区中的内容
ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。
ob_get_contents — 返回输出缓冲区的内容
ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。
ob_get_length — 返回输出缓冲区内容的长度
ob_get_level — 返回输出缓冲机制的嵌套级别
ob_get_status — 得到所有输出缓冲区的状态
ob_gzhandler — 在ob_start中使用的用来压缩输出缓冲区中内容的回调函数。ob_start callback function to gzip output buffer
ob_implicit_flush — 打开/关闭绝对刷送
ob_list_handlers — 列出所有使用中的输出处理程序。
ob_start — 打开输出控制缓冲
output_add_rewrite_var — 添加URL重写器的值(Add URL rewriter values)
output_reset_rewrite_vars — 重设URL重写器的值(Reset URL rewriter values)

http://my.oschina.net/CuZn/blog/68650

 

-------------

flush -- 刷新输出缓冲
说明
void flush ( void )


刷新PHP程序的缓冲,而不论PHP执行在何种情况下(CGI ,web服务器等等)。该函数将当前为止程序的所有输出发送到用户的浏览器。

flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响。因此,必须同时使用 ob_flush() 和flush() 函数来刷新输出缓冲。

个别web服务器程序,特别是Win32下的web服务器程序,在发送结果到浏览器之前,仍然会缓存脚本的输出,直到程序结束为止。

有些Apache的模块,比如mod_gzip,可能自己进行输出缓存,这将导致flush()函数产生的结果不会立即被发送到客户端浏览器。

甚至浏览器也会在显示之前,缓存接收到的内容。例如 Netscape 浏览器会在接受到换行或 html 标记的开头之前缓存内容,并且在接受到 标记之前,不会显示出整个表格。

一些版本的 Microsoft Internet Explorer 只有当接受到的256个字节以后才开始显示该页面,所以必须发送一些额外的空格来让这些浏览器显示页面内容。


ob_flush
(PHP 4 >= 4.2.0, PHP 5)

ob_flush --  Flush (send) the output buffer on/off
Description
void ob_flush ( void )


This function will send the contents of the output buffer (if any). If you want to further process the buffer's contents you have to call ob_get_contents() before ob_flush() as the buffer contents are discarded after ob_flush() is called.

This function does not destroy the output buffer like ob_end_flush() does.


flush和ob_flush的使用上有一些特别注意的地方,造成无法刷新输出缓冲。
一. flush和ob_flush的正确顺序,先ob_flush再flush,如下:
ob_flush();
flush();
如果Web服务器的操作系统是windows系统,那顺序颠倒或者不使用ob_flush()也不会出现问题。但是在Linux系统上就无法刷新输出缓冲。

二. 使用ob_flush()前,确保前面的内容大小足够4069字符。
一些Web服务器的output_buffering默认是4069字符或者更大,即输出内容必须达到4069字符服务器才会flush刷新输出缓冲,为了确保flush有效,最好在ob_flush()函数前有以下语句:
print str_repeat(" ", 4096);
以确保到达output_buffering值。

 

for ($i=1; $i<20; $i++)
{
echo "".$i."";
echo '
';
ob_flush();
flush();
sleep(1);
}
ob_end_flush();