默认情况下,输出一个字符串到浏览器,经过3个阶段PHP buffer->Tcp buffer->浏览器(IE浏览器有的版本也存在buffer)
PHP默认是打开输出缓冲的,在php.ini中可以配置output_buffering=4096(4kb,一个内存页),设置PHP输出缓冲大小
•flush — 刷新输出缓冲(按我的理解是刷新输出TCP bufer)
•ob_clean — 清空(擦掉)输出缓冲区
•ob_end_clean — 清空(擦除)缓冲区并关闭输出缓冲
•ob_end_flush — 冲刷出(送出)输出缓冲区内容并关闭缓冲
•ob_flush — 冲刷出(送出)输出缓冲区中的内容
•ob_get_clean — 得到当前缓冲区的内容并删除当前输出缓。
•ob_get_contents — 返回输出缓冲区的内容
•ob_get_flush — 刷出(送出)缓冲区内容,以字符串形式返回内容,并关闭输出缓冲区。
•ob_get_length — 返回输出缓冲区内容的长度
(PHP 4, PHP 5, PHP 7)
ob_start — 打开输出控制缓冲
$output_callback
[, int $chunk_size
[, bool $erase
]]] )此函数将打开输出缓冲。当输出缓冲激活后,脚本将不会输出内容(除http标头外),相反需要输出的内容被存储在内部缓冲区中
由于IE有的版本会有浏览器buffer(256字节),以下代码均在chrome浏览器下运行
1. ob_start使用说明
ob_start('replace_content'); echo 'Kevin Durant go to Golden State Warriors!'; //David West go to Golden State Warriors! function replace_content($content){ return str_replace('Kevin Durant', 'David West', $content); }
再看下面的代码
ob_end_clean();//必须关闭系统缓冲区 ob_start(null, 1); for($i = 1; $i <=10; $i++){ echo $i,'<br>'; //ob_flush(); flush();//输出TCP缓冲 sleep(1); }
PHP默认开启了一个输出缓冲区,所以先调用ob_end_clean关闭默认的输出缓冲。由于调用ob_start设置该缓冲区大小为1个字节,所以这段代码会每隔1秒输出。
再看下面的代码也可以做到这个效果
for($i = 1; $i <=10; $i++){ echo $i,'<br>'; ob_flush(); flush();//输出TCP缓冲 sleep(1); }
使用了系统默认的输出缓冲区,此时缓冲区大小为默认的4096个字节,所以必须调用ob_flush刷新输出PHP缓冲内容.
2.输出过程
//PHP默认缓冲区F
1 ob_start(); //缓冲区A 2 echo 'champion 1<br />'; 3 ob_start(); //缓冲区B 4 echo 'champion 2<br />'; 5 ob_start(); //缓冲区C 6 echo 'champion 3<br />'; 7 ob_end_clean(); 8 ob_end_flush(); 9 ob_end_clean(); 10 $str = ob_get_contents(); 11 echo $str;
运行结果: 没有输出任何东西
可以把整个缓冲区看作一个栈,有新的缓冲区被创建,则新的缓冲区成为栈顶缓冲区。有新内容输出则输出内容会被输出到栈顶的缓冲区。
本程序缓冲区层次: C->B->A->F
初始F:null
运行 1.ob_start();
后,新建缓冲区A,此时整个缓冲区情况
A:null->F:null
运行 2.echo 'level 1<br />';
后
内容输出到缓冲区A,此时整个缓冲区情况
A:’level 1<br />’ -> F:null
运行 3.ob_start();
后,新建缓冲区B,此时整个缓冲区情况
B:null -> A:’level 1<br />’ -> F:null
运行 4.echo 'level 1<br />';
后
内容输出到缓冲区B,此时整个缓冲区情况
B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null
以此类推建立缓冲区C,运行到 6.echo 'level 3<br />';
后,此时整个缓冲区情况
C:’level 3<br />’ -> B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null
接着运行 7.ob_end_clean();
,缓冲区C被清空且关闭,此时缓冲区情况
B:’level 2<br />’ -> A: ‘level 1<br />’ -> F:null
接着运行 8.ob_end_flush();
,缓冲区B的内容输出到上一级的缓冲区且缓冲区B被关闭。此时缓冲区情况
A: ‘level 2<br /> level 1<br />’ -> F:null
接着运行 9.ob_end_clean();
,缓冲区A被情况且关闭。A的内容还没有真正输出到缓冲区F中就被关闭了,最后只剩F:null,因此程序就没有任何输出了。
可使用ob_get_level()获取输出缓冲机制的嵌套级别
3.ob_clean(), ob_end_clean(), ob_flush(), ob_end_flush()的区别
开始真是傻傻分不清楚,简单的说ob_end_clean()和ob_end_flush()会关闭当前缓冲区,而ob_clean(),ob_flush()不会.
echo 'champion1<br>'; ob_start(); echo 'champion2<br>'; ob_end_clean(); var_dump(ob_get_contents());
echo 'champion1<br>'; ob_start(); echo 'champion2<br>'; ob_enb_clean(); var_dump(ob_get_contents());
相信你可以判断出输出的结果啦。
我们用GD库输出图片的时候,或者ajax接口输出数据之前我们应该使用ob_clean,因为ob_end_clean会关闭当前输出缓冲区,
很明显使用PHP输出缓冲程序效率会更高。