资讯专栏INFORMATION COLUMN

浅析PHP的输出缓冲控制

wangjuntytl / 437人阅读

摘要:默认为是一个回调函数,将脚本的所有输出,用所定义的函数进行处理。在输出缓冲区的回调函数中使用这些函数,会导致未定义的错误。

简介

PHP有输出时,可以用输出控制函数来控制输出

缓冲阶段

ob_start(),将内部缓冲区(buffer)打开。当PHP遇到echo,printf等输出语句时, PHP就会将要输出的数据放入缓冲区(buffer)中,等待输出。而只有当缓冲区满了或者php运行完毕,才将数据输出去。输出字节离开PHP缓冲区进去Apache缓冲区或者Nginx缓冲区(fast-cgi),之后进入浏览器缓冲区。如下所示:

echo,print -> php buffer -> web server buffer(apache缓冲区,fast-cgi缓冲区) -> browser buffer

php.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 : 使用ext/http压缩输出

ob_etaghandler : 使用ext/http自动生成HTTP的Etag

3.implicit_flush

设置为 On 时,打开绝对刷送。
PHP缓冲区层发送数据到web server buffer,Apache自动刷新输出缓冲区,不需要等待刷新指令,直接就把输出返回到browser buffer

设置为 Off 时,关闭绝对刷送。
不自动刷新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 "
Line to show."; echo str_pad("",4096)." "; ob_flush(); flush(); sleep(2); } echo "Done."; ob_end_flush();

但是ob_*系列的函数是操作php buffer,而flush则是操作web server buffer(活着特指上面所提到的Apache缓冲区)。

应用场景

1.首先肯定是提高性能,减少响应次数

2.修改http头信息
我们输出消息到页面表示请求和响应已经完成了,是不能再发送http头信息了。但是使用缓冲区就不一样了

    ob_start();
    echo "Hello
";
    
    setcookie("cookiename", "cookiedata");
    
    ob_end_flush();
    

在上面的例子中,echo函数的输出将一直被保存在输出缓冲区中直到调用 ob_end_flush() 。同时,对setcookie()的调用也成功存储了一个cookie,而不会引起错误。

3.避免内存限制

对于大文件来说, 开启PHP缓冲区, 一段一段的读取数据到浏览器,避免用户等待,也避免一次读取数据读取耗尽内存。

4.静态文件缓存
使用缓冲区生成静态html文件

    ob_start("ob_gzhandler");
    $content = ob_get_contents();
    // 打开文件
    $file = fopen("./index.html", "w");
    // 将缓冲区中的内容写入文件
    fwrite($file, $content);
    fclose($file);
    ob_end_clean();

5.处理输出的内容
eg:进行gzip压缩,进行简繁转换,或者进行一些字符串替换

tips:不要在输出缓冲区回调函数内调用任何缓冲区相关的函数,也不要在回调函数中输出任何东西。是因为有些PHP的内部函数也使用了输出缓冲区,它们会叠加到其他的缓冲区上,这些函数会填满自己的缓冲区然后刷新,或者是返回里面的内容。eg:print_r()、highlight_file()和highlight_file::handle()等。在输出缓冲区的回调函数中使用这些函数,会导致未定义的错误。

参考资料:

[ 1 ] : 深入理解php的输出缓冲区(output buffer)

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/22871.html

相关文章

  • 【Swoole源码研究】浅析swoole中server实现

    摘要:的部分是基于以及协议的。例如父进程向中写入子进程从中读取子进程向中写入父进程从中读取。默认使用对进程进行分配交给对应的线程进行监听线程收到某个进程的数据后会进行处理值得注意的是这个线程可能并不是发送请求的那个线程。 作者:施洪宝 一. 基础知识 1.1 swoole swoole是面向生产环境的php异步网络通信引擎, php开发人员可以利用swoole开发出高性能的server服务。...

    rainyang 评论0 收藏0
  • 浅析缓冲区溢出

    摘要:缓冲区溢出是一种常见的攻击手段,原因在于缓冲区漏洞非常普遍,并且易于实现。缓冲区溢出漏洞占了远程网络攻击的绝大多数,成为远程攻击的主要手段。利用缓冲区溢出攻击可以导致程序运行失败系统崩溃等后果。 最近一直在学习缓冲区溢出漏洞的攻击,但是关于这一块的内容还是需要很多相关知识的基础,例如编程语言及反汇编工具使用。所以研究透彻还需要不少的时间,这里简单的做一个学习的总结,通过具体的实验案例对...

    Hegel_Gu 评论0 收藏0
  • 浅析缓冲区溢出

    摘要:缓冲区溢出是一种常见的攻击手段,原因在于缓冲区漏洞非常普遍,并且易于实现。缓冲区溢出漏洞占了远程网络攻击的绝大多数,成为远程攻击的主要手段。利用缓冲区溢出攻击可以导致程序运行失败系统崩溃等后果。 最近一直在学习缓冲区溢出漏洞的攻击,但是关于这一块的内容还是需要很多相关知识的基础,例如编程语言及反汇编工具使用。所以研究透彻还需要不少的时间,这里简单的做一个学习的总结,通过具体的实验案例对...

    fantix 评论0 收藏0
  • PHP7源码学习】2019-04-25 PHP生命周期浅析

    摘要:在此函数的实现种主要有以下几个函数初始化内部字符串哈希表启动的输出激活引擎激活,进行编译器,重置,执行器以及词法扫描器。 Grape 视频传送门:【每日学习记录】使用录像设备记录每天的学习 今天我们来看下PHP的生命周期,我们都知道PHP生命周期有五个步骤,那么在源码层级是怎么去实现PHP生命周期呢?首先,我们抛出本文的几个问题: php的生命周期是什么?每个阶段做了什么? 为什么...

    zxhaaa 评论0 收藏0
  • Android Vsync 原理浅析

    摘要:这就是卡顿出现的原因和情况。这个时候重复了上一个情况,也是太耗时了,然后又覆盖了下一个发出的时间,再次造成卡顿依次类推,会造成多次卡顿。但是注意了只有在需要时,才会进行三重缓冲。Preface Android中,Client测量和计算布局,SurfaceFlienger(server)用来渲染绘制界面,client和server的是通过匿名共享内存(SharedClient)通信。 每个应用...

    shinezejian 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<