当前位置: 首页 > 后端技术 > PHP

PHP的输出缓冲控制分析

时间:2023-03-29 14:50:32 PHP

简介当PHP有输出时,可以使用输出控制函数来控制输出缓冲阶段ob_start(),打开内部缓冲(buffer)。当PHP遇到echo、printf等输出语句时,PHP会将要输出的数据放入缓冲区(buffer)中等待输出。并且只有当缓冲区已满或php操作结束时,才会输出数据。输出字节离开PHP缓冲区,进入Apache缓冲区或Nginx缓冲区(fast-cgi),然后进入浏览器缓冲区。如下:echo,print->phpbuffer->webserverbuffer(apachebuffer,fast-cgibuffer)->browserbufferphp.ini配置项下面这些函数的行为受php.ini中设置的影响。1.当output_buffering设置为On时,打开内部缓冲区(buffer)并设置为Off,关闭内部缓冲区(buffer)并设置为一个数字,在php.ini中限制输出缓冲区的最大值,output_buffering=4096是默认开启的。此时使用ini_set()改变output_buffering的值是不能生效的。因为在php程序启动的时候输出缓冲层就已经打开了。因此,只能通过编辑php.ini来改变它们的初始值或在执行PHP程序时使用-d选项来改变它们的值。2、output_handler默认值为NULL,是一个回调函数,用定义的函数处理脚本的所有输出。类似于ob_start($output_callback)。$output_callback:ob_gzhandler:使用ext/zlib压缩输出mb_output_handler:使用ext/mbstring转换字符编码ob_iconv_handler:使用ext/iconv转换字符编码ob_tidyhandler:使用ext/tidy整理输出HTML文本ob_[inflate/deflate]_handler:Useext/httpcompressedoutputob_etaghandler:Useext/http自动生成HTTPEtag3.implicit_flush当设置为On时,启用绝对刷新。PHP缓冲层将数据发送到web服务器缓冲区,Apache自动刷新输出缓冲区,直接将输出返回到浏览器缓冲区,无需等待刷新命令。不自动刷新apache缓冲区,接收到数据后,等待php.ini中的刷新命令,implicit_flush=Off默认关闭。如果要刷新Apache缓冲区,请使用PHP的flush()函数手动刷新它。或者调用ob_implicit_flush()(隐式刷新)函数。ob_*系列函数ob_flush和flush在不同使用的时候,我们经常会一起使用if(ob_get_level()==0)ob_start();for($i=0;$i<10;$i++){echo"
要显示的行。";echostr_pad('',4096)."\n";ob_flush();冲洗();睡觉(2);}回声“完成。”;ob_end_flush();但是ob_*系列的功能是操作phpbuffer,而flush是操作webserverbuffer(或者特指上面说的Apachebuffer)。应用场景1.首先要提高性能,减少响应次数。2.修改http头信息。我们向页面输出一条消息,表示请求和响应已经完成,不能再发送http头信息了。但是使用缓冲区是不同的ob_start();echo"你好\n";setcookie("cookiename","cookiedata");ob_end_flush();在上面的示例中,echo函数的输出将始终保存在输出缓冲区中,直到调用ob_end_flush()为止。此外,对setcookie()的调用成功地存储了cookie而没有导致错误。3、避免内存限制对于大文件,打开PHP缓冲区,将数据一段一段地读取到浏览器,避免用户等待,避免一次读取数据耗尽内存。4.静态文件缓存使用buffer生成静态html文件ob_start('ob_gzhandler');$content=ob_get_contents();//打开文件$file=fopen('./index.html','w');//将缓冲区中的内容写入文件fwrite($file,$content);fclose($文件);ob_end_clean();5、对输出内容进行处理eg:进行gzip压缩,进行简繁体转换,或者进行一些字符串替换提示:不要在输出缓冲回调函数中调用任何缓冲相关的函数,也不要在回调函数中输出任何内容。因为一些PHP内部函数也使用输出缓冲区,它们会叠加在其他缓冲区上,这些函数会填充自己的缓冲区然后刷新,或者返回里面的内容。eg:print_r()、highlight_file()、highlight_file::handle()等。在输出缓冲区的回调函数中使用这些函数会导致未定义错误。参考资料:[1]:深入理解php的输出缓冲区(outputbuffer)