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 相关文章推荐
MVC模式的PHP实现
Oct 09 PHP
一周让你学会PHP 不错的学习资料
Feb 06 PHP
ecshop 批量上传(加入自定义属性)
Mar 20 PHP
php_screw 1.5:php加密: 安装与使用详解
Jun 20 PHP
PHP 循环删除无限分类子节点的实现代码
Jun 21 PHP
php使用curl发送json格式数据实例
Dec 17 PHP
thinkphp文件引用与分支结构用法实例
Nov 26 PHP
如何正确配置Nginx + PHP
Jul 15 PHP
PHP封装函数实现生成随机的字符串验证码
Jan 24 PHP
PHP开发中csrf攻击的简单演示和防范
May 07 PHP
PHP利用Cookie设置用户30分钟未操作自动退出功能
Jul 03 PHP
PHP常见过waf webshell以及最简单的检测方法
May 21 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页面执行时间,数据库读写次数,函数调用次数等(THINKphp)
2013/06/03 PHP
php支付宝在线支付接口开发教程
2016/09/19 PHP
PHP 序列化和反序列化函数实例详解
2020/07/18 PHP
基于jquery的下拉框改变动态添加和删除表格实现代码
2020/09/12 Javascript
基于jQuery实现的图片切换焦点图整理
2014/12/07 Javascript
html的DOM中document对象anchors集合用法实例
2015/01/21 Javascript
jQuery使用fadeout实现元素渐隐效果的方法
2015/03/27 Javascript
javascript实现随时变化着的背景颜色
2015/04/02 Javascript
js+css实现上下翻页相册代码分享
2015/08/18 Javascript
JS文字球状放大效果代码分享
2015/08/19 Javascript
jQuery模拟360浏览器切屏效果幻灯片(附demo源码下载)
2016/01/29 Javascript
JavaScript学习笔记之数组随机排序
2016/03/23 Javascript
plupload+artdialog实现多平台上传文件
2016/07/19 Javascript
Angular Module声明和获取重载实例代码
2016/09/14 Javascript
使用jQuery和ajax代替iframe的方法(详解)
2017/04/12 jQuery
Vue的transition-group与Virtual Dom Diff算法的使用
2019/12/09 Javascript
详解 javascript对象创建模式
2020/10/30 Javascript
Vue基于localStorage存储信息代码实例
2020/11/16 Javascript
python thread 并发且顺序运行示例
2009/04/09 Python
Python 自动补全(vim)
2014/11/30 Python
详解python3实现的web端json通信协议
2016/12/29 Python
完美解决Python2操作中文名文件乱码的问题
2017/01/04 Python
如何通过python实现全排列
2020/02/11 Python
详解Python遍历列表时删除元素的正确做法
2021/01/07 Python
印度尼西亚在线时尚购物网站:ZALORA印尼
2016/08/02 全球购物
Lampenwelt德国:欧洲领先的灯具和照明在线商店
2018/08/05 全球购物
大学生旷课检讨书
2014/01/22 职场文书
广告学毕业生求职信
2014/01/30 职场文书
文科毕业生自荐书范文
2014/04/17 职场文书
小学生中国梦演讲稿
2014/04/23 职场文书
大学生个人求职信例文
2014/07/07 职场文书
Java Socket实现Redis客户端的详细说明
2021/05/26 Redis
深入理解以DEBUG方式线程的底层运行原理
2021/06/21 Java/Android
浅谈MySQL中的六种日志
2022/03/23 MySQL
你真的会用Mysql的explain吗
2022/03/31 MySQL
Python实现仓库管理系统
2022/05/30 Python