资讯专栏INFORMATION COLUMN

PHP基础之输出缓冲区基本概念、原理分析

harryhappy / 1416人阅读

摘要:返回内部缓冲区的内容,关闭缓冲区。返回缓冲区的长度,如果缓冲区未被激活,则返回。得到所有输出缓冲区的状态。使用输出缓冲,可以将读取的文件读入缓冲区,达到一定大小时传送给用户,再继续读取,实现分片的效果。

一、概念

在PHP运行的过程中,可以将会产生输出的函数或操作结果暂时保存在PHP的缓冲区,只有当缓冲区满了、或者PHP运行完毕、或者在必要时候进行输出,才会将数据输出到浏览器,此缓冲数据的区域称为PHP的输出缓冲区(OB)。

二、原理

①使用了缓冲区之后,当执行PHP的时候,如果碰到了echo、print_r之类的会输出数据的代码(实际上许多函数都会产生输出),PHP就会将要输出的数据放到PHP自身的缓冲区,等待输出;

②当PHP自身的缓冲区接到指令,指示要输出缓冲区的内容时,将会把缓冲区内的数据输出到服务器上, 服务器接受到PHP输出的数据,然后再把该数据存在到服务器自身的缓冲区内,等到输出;

③当服务器接受到指令,只是要输出缓冲区的内容时, 将会把缓冲区的内容输出,返回到浏览器。

上面可以看出,输出缓冲区层不是唯一用于缓冲输出的层,它实际上只是很多层中的一个。最后一点你要记住输出缓冲区层的行为跟你使用的SAPI(web或cli)相关,不同的SAPI可能有不同的行为。

第一点概念有提到,缓冲区满了会将缓冲数据输出,这个跟SAPI有关,缓冲区主要是通过php.ini中的output_buffering变量控制。output_buffering的默认是on,默认值是4096(4kb)。

三、输出缓冲区的配置

1、以我们通常使用的PHP-FPM这种SAPI为例,这里总结一下php的ini文件配置,主要为三个选项:

output_buffering
implicit_flush
output_handler

通过一个表格来理清一下这三个参数的含义:

注意,以上三个值不能在运行时使用ini_set()改这几个选项的值。

2、关于PHP CLI方式执行时的配置,与FPM不太一样,有几点需要注意的是:

(1) output_buffering参数默认是不开启的,

(2) implicit_flush参数默认被置为1(开启)。

3、关于output_handler设置回调函数,可参考一下几个常用设置:

①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;

四、输出缓冲区相关方法

ob_start(); //打开一个输出缓冲区,所有的输出信息不再直接发送到下一层,而是保存在输出缓冲区里面。
ob_clean(); //删除内部缓冲区的内容,不关闭缓冲区(不输出)。
ob_end_clean(); //删除内部缓冲区的内容,关闭缓冲区(不输出)。
ob_get_clean(); //返回内部缓冲区的内容,关闭缓冲区。
ob_flush(); //发送缓冲区内容到下一层,删除缓冲区内容,不关闭缓冲区。
ob_end_flush(); //发送缓冲区内容到下一层,删除缓冲区的内容,关闭缓冲区。
ob_get_flush(); //返回缓冲区的内容,并关闭缓冲区,再释放缓冲区的内容。
ob_get_contents(); //返回缓冲区的内容,不输出。
ob_get_length(); //返回缓冲区的长度,如果缓冲区未被激活,则返回FALSE。
ob_get_status() ; //得到所有输出缓冲区的状态。
ob_implicit_flush(); //打开/关闭绝对刷送。

五、输出缓冲区的应用

1、在session、cookie、header等设置函数之前开启:

最常见的就是在使用header函数之前,就已经输出了某些数据,这样会导致某些错误,例如 Cannot modify header information – headers already sent by;

出现这个错误的原因是, 在header之前已经输出了某些数据,而输出这些数据的同时, 服务器将会同时发送一个响应状态到浏览器上(既然有输出,即这个请求是有效的),而其后你又再次使用header函数

发送http头,则会返回这个错误,错误的意思是:HTTP头已经发送出去了,你不能对他再做修改。

因此可以在开头先开启ob_start方法。

2、控制PHP程序的下载功能:

通常很多人会用PHP实现文件下载,但是当一个文件大小过大(例如100M)时,如果先全部读入内存再传送给用户,会导致响应时间大大加长(甚至超时),同时内存占用也会大大增加(甚至溢出)。

使用输出缓冲,可以将读取的文件读入缓冲区,达到一定大小时传送给用户,再继续读取,实现分片的效果。这样浏览器就可以持续地接受到数据,而不必等到所有文件读取完毕,同时内存也不会占用太大。

3、作为静态文件缓存:

将需要多次反复读取,并且求改频率很低的文件,第一次读取时放入缓冲区,生成静态文件,之后每次读取可以直接返回而不需要进过php的处理(读取数据库等)。

您可能感兴趣的文章:
PHP缓冲区用法总结

PHP中对缓冲区的控制实现代码

刷新PHP缓冲区为你的站点加速

PHP5.0 TIDY_PARSE_FILE缓冲区溢出漏洞的解决方案

php中的buffer缓冲区用法分析

php flush类输出缓冲剖析

php中ob(Output Buffer 输出缓冲)函数使用方法

PHP 输出缓冲控制(Output Control)详解

php缓冲输出实例分析

剖析 PHP 中的输出缓冲

PHP输出缓冲控制Output Control系列函数详解

PHP嵌套输出缓冲代码实例

文章同步发布: https://www.geek-share.com/de...

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

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

相关文章

  • PHP面试二:高并发与大数据

    摘要:三态分别是就绪运行阻塞进程的五态模型在三态的基础上发展而来新建态运行态终止态就绪态等待态线程称之为轻量级的进程,程序执行流的最小单元。一个进程下有多个线程来完成不同的工作称之为多线程。 web资源防盗链 盗链是什么? 为什么要防? 在自己页面上显示一些不是自己服务器的资源(图片、音频、视频、css、js等)由于别人盗链你的资源会加重你的服务器负担,所以我们需要防止可能会影响统计 防盗链...

    Ashin 评论0 收藏0
  • 我的阿里路+Java面经考点

    摘要:我的是忙碌的一年,从年初备战实习春招,年三十都在死磕源码,三月份经历了阿里五次面试,四月顺利收到实习。因为我心理很清楚,我的目标是阿里。所以在收到阿里之后的那晚,我重新规划了接下来的学习计划,将我的短期目标更新成拿下阿里转正。 我的2017是忙碌的一年,从年初备战实习春招,年三十都在死磕JDK源码,三月份经历了阿里五次面试,四月顺利收到实习offer。然后五月怀着忐忑的心情开始了蚂蚁金...

    姘搁『 评论0 收藏0
  • PHP中的pack和unpack函数

    摘要:鉴于文件读写网络编程,或者说字节流处理的重要性,掌握这两个函数是迈向高级编程的基础。相比之下字节处理门庭冷落,相关函数寥寥无几。上述是函数简单的使用场景,接下来分别介绍和函数。如其名,函数的工作是将数据按照格式打包成字节数组。 转载请注明文章出处:https://tlanyan.me/php-pack-a... PHP有两个重要的冷门函数:pack和unpack。在网络编程,读写图像...

    Lin_R 评论0 收藏0
  • php底层原理垃圾回收机制

    摘要:总结垃圾回收机制以的引用计数机制为基础以前只有该机制同时使用根缓冲区机制,当发现有存在循环引用的时,就会把其投入到根缓冲区,当根缓冲区达到配置文件中的指定数量后,就会进行垃圾回收,以此解决循环引用导致的内存泄漏问题开始引入该机制 php垃圾回收机制,对于PHPer来说是一个不陌生但是又不是很熟悉的内容。那么php是怎么实现对不需要的内存进行回收的呢? php变量的内部存储结构 首先还是...

    light 评论0 收藏0

发表评论

0条评论

harryhappy

|高级讲师

TA的文章

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