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

PHP中的输出缓冲控制

时间:2023-03-29 15:34:55 PHP

在PHP中,当我们直接执行echo或print_r时,会直接打印输出内容。但是,在某些情况下,我们不想直接打印。这时候我们就可以使用outputbuffercontrol来控制输出打印。当然,这套功能不仅仅局限于打印内容,我们还可以做其他的操作,这个我们最后再说。清除输出首先,让我们看一下从打印输出中保留回声之类的东西。ob_start();echo111,PHP_EOL;echo"aaaa",PHP_EOL;ob_end_clean();相信很多朋友应该都看过ob_start()这个函数,它的作用就是开始一段输出缓冲控制。ob_start()之后代码中的输出语句都会进入输出缓冲区。这时,如果我们调用ob_end_clean()、ob_clean()或ob_get_clean(),将没有输出。它们三个的作用都是清空输出缓冲区的内容。具体区别可以参考文末给出的功能说明或官方文档。获取输出缓冲区的内容ob_start();echo111,PHP_EOL;echo"aaaa",PHP_EOL;$v=ob_get_contents();ob_end_clean();echo$v;上面提到,使用ob_end_clean()会清除输出缓冲区的内容,但是在这段代码中,我们使用ob_get_contents()函数直接将缓冲区的内容赋值给变量\$v。这个时候$v里面就包含了前面两段echo的内容,也就是说我们已经得到了这组操作应该由自己输出的内容,并保存在一个变量中。这样做有什么用?我们可以得到phpinfo()、var_dump()等直接输出函数的内容,不会打印到客户端屏幕上。例如:ob_start();php_info();$v=ob_get_contents();ob_end_clean();echo$v;$v中的内容是php_info()的内容。这是输出缓冲区控件的第二个功能。刷新(输出)缓冲区内容ob_start();echo111,PHP_EOL;echo"aaaa",PHP_EOL;flush();ob_flush();同样,我们想直接再次输出缓冲区中的内容,使用flush(),ob_flush()、ob_end_flush()和ob_get_flush()就够了,其实相当于让ob_start()重新生效后的echo等输出语句正常输出。另外,我们还可以使用一个函数来自动刷新。ob_implicit_flush();ob_start();回显111,PHP_EOL;echo"aaaa",PHP_EOL;使用ob_implicit_flush()后,我们就不需要手动调用ob_flush()等函数来刷新缓冲区内容了。一些检测函数ob_start();ob_start();echo123,PHP_EOL;echoob_get_length(),PHP_EOL;//3echoob_get_level(),PHP_EOL;//2print_r(ob_get_status(true));//Array//(//[0]=>Array//(//[name]=>默认输出处理程序//[type]=>0//[flags]=>112//[level]=>0//[chunk_size]=>0//[buffer_size]=>16384//[buffer_used]=>0//)//[1]=>Array//(//[name]=>默认输出处理程序//[type]=>0//[flags]=>112//[level]=>1//[chunk_size]=>0//[buffer_size]=>16384//[buffer_used]=>17//)//)ob_get_flush();ob_get_length()会返回当前缓冲区内容的长度,这里我们只打印了一个123,在缓冲区中保存了3个字符,所以输出正好是3。ob_get_level()返回当前缓冲区的级别,注意上面我们调用了两次ob_start(),也就是有两层buffer,这个buffer是可以嵌套的。ob_get_status()函数是buffer的状态信息,各个字段的描述可以在官方文档中找到,这里不再赘述。使用ob_start()的回调函数替换输出缓冲区的内容。这是一个例子,但它可以扩展到其他功能,比如全局输出过滤、CSS或JS文件的压缩优化等。ob_start(function($text){return(str_replace("apples","oranges",$text));});echo"这就像比较苹果和橘子",PHP_EOL;ob_get_flush();//就像比较橙子tooranges的最终输出是用橙子的内容替换苹果的内容。添加URL重写器output_add_rewrite_var('var','value');//somelinkscho'linklink2';//link//link2//aformecho'';////////上面的你看到代码中的任何线索了吗?没错,使用output_add_rewrite_var()函数,我们可以在PHP输出的时候给HTML链接或者表单代码加上一个参数。有没有想过什么使用场景?防止对POST表单的CSRF攻击。这个功能会根据php.ini文件中的url_rewriter.tags配置项来添加。默认情况下,该配置项只支持from形式。同时还可以支持a标签的href、area标签的href、frame标签的src、input标签的src等,即自动给对应的属性添加字段这些标签。当然它还有一个反函数output_reset_rewrite_vars()来取消之前添加的参数。总结输出缓冲控件还有很多有趣的地方,但是限于篇幅,我们先介绍到这里,以后有什么好的功能的应用再说明。现在基于Swoole的应用越来越多。当我们需要将TP、Laravel等传统框架转换为支持Swoole时,往往需要使用输出缓冲控制来修改入口文件。因为传统的框架基本上是直接输出echo之类的,但是在Swoole中,echo的内容是直接打印在console上的,这就需要我们通过ob_get_contents()能力获取所有的输出,然后通过response->end()用于实际响应。此外,还有一些其他场景也使用输出缓冲控制:1、在PHP中,header()、session_start()、setcookie()等发送头文件的函数之前,不能有任何输出。使用outputbuffercontrol函数可以在这些函数之前输出而不报错2.对输出内容进行处理,比如生成静态缓存文件,进行gzip压缩输出,这是比较常用的函数3.捕获一些无法获取的函数输出,比如phpinfo()、var_dump()等,这些函数会在浏览器中显示运行结果,如果我们要对这些结果进行处理,使用输出缓冲控制函数是一个很好的方法。简单的说,这类函数是没有返回值的,要获取这些函数的输出数据,就要用到输出缓冲控制函数。4、部分数据的实时输出最后给出了输出缓冲控制相关功能说明,具体内容请多阅读官方文档。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回调函数到gzip输出缓冲区ob_implicit_flush—打开/关闭绝对刷新ob_list_handlers—列出所有正在使用的输出处理程序。ob_start—打开输出控制缓冲区output_add_rewrite_var—添加URL重写器值(AddURLrewritervalues)output_reset_rewrite_vars—ResetURLrewritervalues(重置URL重写器值)测试代码:https://github.com/zhangyue0503/dev-blog/blob/master/php/202005/source/%E8%BF%98%E6%90%9E%E4%B8%8D%E6%87%82PHP%E4%B8%AD%E7%9A%84%E8%BE%93%E5%87%BA%E7%BC%93%E5%86%B2%E6%8E%A7%E5%88%B6%EF%BC%9F.php参考文档:https://www.php.net/manual/zh/ref.outcontrol.phphttps://www.php.net/manual/zh/session.configuration.php#ini.url-rewriter.tagshttps://blog.csdn.net/xiaofan1988/article/details/43124359============各媒体平台均可搜索【硬核项目经理】