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


Posted in PHP onJune 19, 2019

本文实例讲述了PHP基础之输出缓冲区。分享给大家供大家参考,具体如下:

一、概念

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

二、原理

①使用了缓冲区之后,当执行PHP的时候,如果碰到了echoprint_r之类的会输出数据的代码(实际上许多函数都会产生输出),PHP就会将要输出的数据放到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

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

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

注意,以上三个值不能在运行时使用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中实现图片的锐化
Oct 09 PHP
PHP iconv 函数转gb2312的bug解决方法
Oct 11 PHP
把1316这个数表示成两个数的和,其中一个为13的倍数,另一个是11的倍数,求这两个数。
Jun 24 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
Apr 23 PHP
使用Apache的htaccess防止图片被盗链的解决方法
Apr 27 PHP
VIM中设置php自动缩进为4个空格的方法详解
Jun 14 PHP
更改localhost为其他名字的方法
Feb 10 PHP
php对象和数组相互转换的方法
May 12 PHP
PHP+iframe图片上传实现即时刷新效果
Nov 18 PHP
PHP面向对象五大原则之依赖倒置原则(DIP)详解
Apr 08 PHP
PHP使用PDO、mysqli扩展实现与数据库交互操作详解
Jul 20 PHP
Swoole源码中如何查询Websocket的连接问题详解
Aug 30 PHP
PHP进阶学习之Geo的地图定位算法详解
Jun 19 #PHP
PHP进阶学习之依赖注入与Ioc容器详解
Jun 19 #PHP
yii2 在控制器中验证请求参数的使用方法
Jun 19 #PHP
php自定义排序uasort函数示例【二维数组按指定键值排序】
Jun 19 #PHP
windows 2008r2+php5.6.28环境搭建详细过程
Jun 18 #PHP
PHP进阶学习之类的自动加载机制原理分析
Jun 18 #PHP
PHP进阶学习之垃圾回收机制详解
Jun 18 #PHP
You might like
php为什么选mysql作为数据库? Mysql 创建用户方法
2007/07/02 PHP
PHP持久连接mysql_pconnect()函数使用介绍
2012/02/05 PHP
基于PHP Web开发MVC框架的Smarty使用说明
2013/04/19 PHP
深入分析php中接口与抽象类的区别
2013/06/08 PHP
laravel Validator ajax返回错误信息的方法
2019/09/29 PHP
laravel5.1 ajax post 传值_token示例
2019/10/24 PHP
js的逻辑运算符 ||
2010/05/31 Javascript
jQuery Ajax使用实例
2015/04/16 Javascript
探析浏览器执行JavaScript脚本加载与代码执行顺序
2016/01/12 Javascript
如何高效率去掉js数组中的重复项
2016/04/12 Javascript
js style.display=block显示布局错乱问题的解决方法
2016/09/21 Javascript
jQuery EasyUI Accordion可伸缩面板组件使用详解
2017/02/28 Javascript
详解vue-cli + webpack 多页面实例配置优化方法
2017/07/13 Javascript
详解Vue.js组件可复用性的混合(mixin)方式和自定义指令
2017/09/06 Javascript
AngularJs用户登录问题处理(交互及验证、阻止FQ处理)
2017/10/26 Javascript
BootStrap modal实现拖拽功能
2018/12/01 Javascript
关于uniApp editor微信滑动问题
2021/01/15 Javascript
[43:47]完美世界DOTA2联赛PWL S3 LBZS vs Phoenix 第一场 12.09
2020/12/11 DOTA
Python中比较特别的除法运算和幂运算介绍
2015/04/05 Python
python实现简单中文词频统计示例
2017/11/08 Python
python保存字典和读取字典的实例代码
2019/07/07 Python
numpy.transpose()实现数组的转置例子
2019/12/02 Python
运行Python编写的程序方法实例
2020/10/21 Python
python3实现飞机大战
2020/11/29 Python
美国内衣第一品牌:Hanes(恒适)
2016/07/29 全球购物
美国购买汽车零件网站:Buy Auto Parts
2018/04/02 全球购物
萨克斯第五大道英国:Saks Fifth Avenue英国
2019/04/01 全球购物
医院辞职信范文
2014/01/17 职场文书
电气自动化求职信
2014/06/24 职场文书
投标文件签署授权委托书范本
2014/10/12 职场文书
高三英语教学计划
2015/01/23 职场文书
2021年国产动漫公司排行前十名,玄机科技上榜,第二推出过铠甲勇士
2022/03/18 杂记
世界十大评分最高的动漫,CLANNAD上榜,第八赚足人们眼泪
2022/03/18 日漫
JAVA 线程池(池化技术)的实现原理
2022/04/28 Java/Android
关于Redis的主从复制及哨兵问题
2022/06/16 Redis
spring boot实现文件上传
2022/08/14 Java/Android