output buffering 输出缓存控制导出大数据及ob_函数拓展笔记

本文介绍了如何使用PHP的输出控制函数(如ob_start、ob_flush等)来处理大数据CSV导出,避免一次性加载大量数据导致内存溢出。通过设置标题,逐批读取数据并及时刷新缓冲区,可以有效地分批次导出数据,提高效率。同时,文章还提及了ob_gzhandler用于压缩输出内容,以减小文件大小。最后,讨论了静态模板技术和输出缓存句柄在现代前后端分离项目中的应用及其局限性。
摘要由CSDN通过智能技术生成

今日刚好做比较大数据的csv 数据导出,有用到ob 函数,故整理输出控制函数相关知识

output buffering

当PHP脚本有输出时,输出控制函数可以用这些来控制输出。这在多种不同情况中非常有用,尤其是用来在脚本开始输出 数据后,发送http头信息到浏览器。输出控制函数不影响由 header() 或 setcookie()发送的文件头信息,仅影响象 echo这样的函数和PHP代码块间的数据

Output Control 函数

  • ob_start(); //打开一个输出缓冲区,所有的输出信息不再直接发送到浏览器,而是保存在输出缓冲区里面。
  • ob_clean(); //删除内部缓冲区的内容,不关闭缓冲区(不输出)。
  • ob_end_clean(); //删除内部缓冲区的内容,关闭缓冲区(不输出)。
  • ob_get_clean(); //返回内部缓冲区的内容,关闭缓冲区。相当于执行 ob_get_contents() and ob_end_clean()
  • ob_flush(); //发送内部缓冲区的内容到浏览器,删除缓冲区的内容,不关闭缓冲区。
  • ob_end_flush(); //发送内部缓冲区的内容到浏览器,删除缓冲区的内容,关闭缓冲区。
  • ob_get_flush(); //返回内部缓冲区的内容,并关闭缓冲区,再释放缓冲区的内容。相当于 ob_end_flush()并返回缓冲区内容。
  • flush(); //将ob_flush释放出来的内容,以及不在PHP缓冲区中的内容,全部输出至浏览器;刷新内部缓冲区的内容,并输出。
  • ob_get_contents(); //返回缓冲区的内容,不输出。
  • ob_get_length(); //返回内部缓冲区的长度,如果缓冲区未被激活,该函数返回FALSE。
  • ob_get_level(); //Return the nesting level of the output buffering mechanism.
  • ob_get_status(); //Get status of output buffers.
  • ob_implicit_flush(); //打开或关闭绝对刷新,默认为关闭,打开后ob_implicit_flush(true),所谓绝对刷新,即当有输出语句(e.g: echo)被执行时,便把输出直接发送到浏览器,而不再需要调用flush()或等到脚本结束时才输出。
  • ob_gzhandler //ob_start回调函数,用gzip压缩缓冲区的内容。
  • ob_list_handlers //List all output handlers in use
  • output_add_rewrite_var //Add URL rewriter values
  • output_reset_rewrite_vars //Reset URL rewriter values

应用

  1. 大数据csv导出
set_time_limit(0);
...
//打开php标准输出流
//以写入追加的方式打开
$fp = fopen('php://output', 'a');

 //设置标题, todo iconv
$title = array('用户id', '用户昵称', '注册时间', '联系电话');
 //将标题写到标准输出中
 fputcsv($fp, $title);

//batch 是继承\Iterator 的迭代器,有效减少内存
        foreach ($query->batch(1000) as $batch) {
            foreach ($batch  as $item) {
                $row = [
                    $item['user_id'],
                    $item->user['nickname'] ?? '',//
                    date('Y-m-d H:i:s', $item->user['created_at'] ?? 0),
                    $item->phone ?? '',
                ];

                fputcsv($fp, array_values($row));
            }

            //刷新缓冲区
            ob_flush();
            flush();
        }
        die();

flush()函数将当前为止程序的所有输出发送到用户的浏览器。flush() 函数不会对服务器或客户端浏览器的缓存模式产生影响。ob_flush是把数据从PHP的缓冲中释放出来,flush是把缓冲内/外的数据全部发送到浏览器

  1. 静态模版技术,这个对于目前大部分项目都前后端分离来说,这个作用应该用的很少了。
  2. 运用ob_get_contents()模板内容处理,比如发送邮件需要模板变量处理,然后把模板内容发送过去,但是目前市面上的很多产品都是在第三方自建模板传模板参数就可以了,所以感觉这种目前用的越来越少
  3. 输出缓存句柄ob_gzhandler,采用输出缓存句柄的方法确实非常有效,而且不会给服务器带来什么特殊的负荷。但必须注意的是,Netscape Communicator对压缩图形的支持不佳,因此除非你能够保证所有用户都使用IE浏览器,否则你应该禁止压缩JPEG和GIF图形。一般地,对于所有其他文件,这种压缩都有效,但建议你针对各种浏览器都分别进行测试,特别是当你使用了特殊的插件或者数据查看器时这一点尤其重要。要将第二个参数传递给ob_gzhandler(),它指定应该使用的压缩级别(我假设是1-9与gzip二进制文件一样,9使用最多的处理器和时间,4是标准的IIRC eg: ob_start(array(‘ob_gzhandler’,9));

总结

  1. 不管上面的哪一种应用都是灵活的基于ob 函数,只要有这种认知,结合项目实际相信还是有花一样的玩法;
  2. PHP脚本运行结束后,会自动刷新缓冲区并输出内容

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值