您的位置:首页 > 编程语言 > PHP开发

php 输出缓冲控制(Output Control )

2016-08-20 22:43 573 查看
php输出缓冲,输出控制是两个概念。输出缓冲,是指php有一个输出缓冲区。输出控制,是指对输出缓冲区进行控制。

具体是应该叫缓冲区还是缓冲器不是那么重要。我们一起来理解一下缓冲(buffer)的概念。

当我们在编辑一个文档的时候,不是我们每在屏幕上敲一个字就向磁盘保存一个字,这样会对磁盘造成很大的伤害,从而减少磁盘的使用寿命,聪明的工程师们就想了个办法,先把内容放进缓冲区,当缓冲区满了或我们执行保存操作的时候,才向磁盘写入缓冲区里的内容。

php缓冲区和我们上面说的缓冲区是一个道理。

当我们执行echo 或 var_dump或类似的输出函数时其执行流程如下:

              echo     =>   php output_buffering => webServer buffer => browser buffer => 输出给用户

  即: 脚本输出  =>      php缓冲区              =>   服务器缓冲区     =>   浏览器缓冲区 =>   显示给用户   

那么如何对这些缓冲区进行设置呢?   

php buffer

可以在php.ini 中设置 php buffer 的值

; Default Value: Off

; Development Value: 4096

; Production Value: 4096

; http://php.net/output-buffering
output_buffering = on       

    output_buffering  默认是关闭的 可以设置为on来打开(大小为默认值4096),或者设置为大于0的数字来打开。

webServer buffer

此处的设置是关于服务器的知识,超出了本文的讨论范围,此处暂不做讨论,以后涉及到服务器再补充

browser buffer 

浏览器缓冲区,没有找到相关的设置方法,只能通过输出大量数据来填满浏览器缓冲区来达到及时输出的测试目的

如何验证以上说法呢,用事实说话,上测试代码。由于本人对apache服务器的了解有限,一下测试结果带有一定的局限性,不过能从原理上解释 php buffer  wenServer buffer 和 browser buffer

测试环境 windows下apache+php  apache的缓冲未开启 谷歌浏览器

以下是我的测试结果供大家借鉴:

// test1 验证浏览器缓冲区存在
// output_buffering = Off
// 执行结果为5秒后一起输出
// 此结论验证了浏览器缓冲的存在,因为php apache 的缓冲区均已关闭
for($i=0;$i<5;$i++){
echo $i.'<br/>';
sleep(1);
}

// test2 验证浏览器缓冲区满了会输出
// output_buffering = Off
// 执行结果为每秒输出一次
// 在程序的每次输出都用$j个*号填充浏览器缓冲区
// 此结论验证了浏览器缓冲的存在,并且浏览器缓冲区满了之后会向用户输出
// 因为php apache 的缓冲区均已关闭
// 适当调整$j的值可以大概推测出浏览器缓冲区的大小
for($i=0;$i<5;$i++){
$j = 8000;
echo $i.str_repeat('*',$j).'<br/>';
sleep(1);
}

// test3 验证php缓冲区存在  与 php缓冲区填满后会自动向浏览器输出
// output_buffering = On
// 执行结果5秒后一起输出
// 在test2中的测试总结出我的浏览器当$j为8000的时候可以控制每秒输出一次
// 也就是说8000个*可以一次填满浏览器的缓冲区,而打开php的缓冲区的时候
// 就变为了5秒后一起输出,证明php缓冲区的存在  没有直接向浏览器输出,而适当调节$j的值,仍然可以看到一秒输出一行的效果,说明php缓冲区满了之后会将数据输出
for($i=0;$i<5;$i++){
$j = 10000;
echo $i.str_repeat('*',$j).'<br/>';
sleep(1);
}


以上结果验证了浏览器缓冲区 及php 缓冲区的存在以及php脚本输出后要输出的内容先经过了php缓冲区 再经过浏览器缓冲区 最后才显示到用户面前 不难猜测数webServer作为php和浏览器的中间层,如果其开启了缓冲区肯定会缓冲php脚本到浏览器之间的输出。

有三种情况会使缓冲区的内容输出

1.显示调用了ob_flush之类的刷出函数

2.缓冲区溢出

3.脚本执行完毕

如何对输出进行控制

那要详细了解一下php的 ob_xx(output buffering)系列函数    Output Control 函数

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)

使用注意事项:

       在php.ini 中 output_buffering  选项设置为 On 时,将在所有的脚本中使用输出控制。如果要限制输出缓冲区的最大值,可将该选项设定为指定的最大字节数(例如 output_buffering=4096)。

        当仅仅设置为On时,表示不限制缓冲区大小,但php.ini中注释其默认大小为4096,说明php对其进行了限制,限制为4096个字节。

        当手动使用ob_start()函数开启输出缓冲区时,则没有默认4096的限制,不过也不能往缓冲区放无限大的数据,因为电脑的内存毕竟有限,这里我们大胆猜测,其上限为memory_limit 设置的值,当然memory_limit
的值可以自己修改,但是无限制放大memory_limit 的值会拖垮服务器。所以我们不建议无限放大其值。

      当output_buffering的值为On或为固定大于零的整数时。我们可以调用ob函数对其操作。但是output_buffering 的值为Off时,调用相关ob函数会报错。所以为了安全起见,我们每次调用ob函数对缓冲区进行控制时,都要调用ob_start()函数,手动开启一个缓冲区。

      ob函数的一些使用细节,请移步http://my.oschina.net/whrlmc/blog/85782
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: