PHP缓冲区的了解(buffer)

本文为作者原创内容,未经许可,禁止转载。如您发现侵权行为,请联系我们


PHP是如何将内容输出到浏览器

我们知道,PHP脚本进程在进行完成的时候,会自动将缓冲区中的内容冲刷到浏览器上,浏览器接受内容,进行解析并展示。

比如如果在PHP脚本文件中直接写入HTML代码:

<html>
<body>
<p>I like oranges.</p>
</body>
</html>


在浏览器上执行脚本,发现浏览器上输出“I like oranges”。说明PHP再脚本结束之后将所有的内容冲刷到浏览器,浏览器解析HTML结构,输出字符串。

什么是缓冲器呢?即buffer,在内存中就是一个默认大小的空间,buffer的存在目的就是为了解决速度不平衡而设计的,CPU的速度跟外部设备的速度不是一个等量级的,如果每次CPU的输出结果都直接传送给外部设备,就是造成CPU资源的浪费,因为CPU一直在等它啊。所以,在内存中开辟一个空间存放这类输出数据,等装满的时候再送给外部设备。

在PHP中的数据输出经历了两个缓冲区,一个是PHP自带的缓冲区,另一个就是Apache的缓冲区(如果服务器是Apache的话)。如PHP中用到的echo,print等也是先放在PHP的缓冲器中即php buffer。等缓冲器满了之后会将内容输出到Apache缓冲器中,Apache等待输出命令,然后将内容输出到浏览器中。

当然,我们也可以主动的让buffer将内容输出来,比如上面的脚本结束就冲出buffer中的内容,除此之外,PHP提供了一些函数让我们可以对buffer中的内容进行操作。


ob_start();
这个函数的作用就是开启buffer,脚本将不再输出内容(除了http标头之外),而是将所有的内容输出到内部的缓冲区中。

第一个参数是个回调函数,我们可以用匿名函数充当回调函数进行如下操作。

ob_start(function($buffer){
return str_replace('you','her',$buffer);
});

这个回调函数将在缓冲区冲刷的时候进行调用,或者是脚本结束时候调用,回调函数的参数就是缓冲区中的内容,上述例子是将缓冲区中的字符串中的you替换成her就行输出。

回调函数如果返回FALSE,buffer中的内容将会原样输出。

有个问题突然想到,ob_start开启之后会不会对已经在缓冲器中的数据造成影响呢,经过我的测试,答案是会的。如:
<?php
echo 11;
echo ob_get_contents();
?>

浏览器输出 11,11,说明echo的数据的确是存放在了PHP缓冲区中,我们直接通过ob_get_contents可以拿到这个数据。


接着看一个例子:
<?php
echo 11;
ob_start(function ($buffer){
if (!$buffer) {
return '这里好像是空的哦';
}
});
echo 22;
?>

浏览器执行只输出 11,说明在ob_start启用时,会将之前PHP缓冲区中的数据送出,然后echo 22,数据被送到缓冲区,在脚本结束的时候回调匿名函数,判断缓冲区内容是否为空,如果为空输出汉字提示,否则将缓冲区中的内容屏蔽不输出,然后屏蔽了22。


其他的几个函数:
ob_end_flush();送出缓冲区的内容并关闭缓冲区
ob_clean();清空缓冲区
ob_flush();冲刷送出缓冲区的内容
ob_get_contents();获取缓冲区的内容
    

注:输出缓冲是可以堆叠的,我们要保证ob_start与ob_end_flush成对出现。