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 4.2书写安全的脚本
Oct 09 PHP
让你的PHP同时支持GIF、png、JPEG
Oct 09 PHP
PHP二维数组的去重问题解析
Jul 17 PHP
使用Curl进行抓取远程内容时url中文编码问题示例探讨
Oct 29 PHP
PHP中的多行字符串传递给JavaScript的两种方法
Jun 19 PHP
PHP+Ajax检测用户名或邮件注册时是否已经存在实例教程
Aug 23 PHP
PHP简单实现DES加密解密的方法
Jul 12 PHP
php+Memcached实现简单留言板功能示例
Feb 15 PHP
一个实用的php验证码类
Jul 06 PHP
php实现微信分享朋友链接功能
Feb 18 PHP
PHP开发实现快递查询功能详解
Apr 08 PHP
php用wangeditor3实现图片上传功能
Aug 22 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
后宫无数却洁身自好的男主,唐三只爱小舞
2020/03/02 国漫
解决Codeigniter不能上传rar和zip压缩包问题
2014/03/07 PHP
用 Composer构建自己的 PHP 框架之使用 ORM
2014/10/30 PHP
linux中cd命令使用详解
2015/01/08 PHP
PHP基于SPL实现的迭代器模式示例
2018/04/22 PHP
JavaScript 学习 - 提高篇
2007/02/02 Javascript
Javascript学习笔记一 之 数据类型
2010/12/15 Javascript
JS弹出层单纯的绝对定位居中示例代码
2014/02/18 Javascript
js字符串完全替换函数分享
2014/12/03 Javascript
限制上传文件大小和格式的jQuery插件实例
2015/01/24 Javascript
13个PHP函数超实用
2015/10/21 Javascript
用瀑布流的方式在网页上插入图片的简单实现方法
2016/09/23 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
使用vue制作探探滑动堆叠组件的实例代码
2018/03/07 Javascript
react项目实践之webpack-dev-serve
2018/09/14 Javascript
vue element table 表格请求后台排序的方法
2018/09/28 Javascript
JavaScript JMap类定义与使用方法示例
2019/01/22 Javascript
javascript数组常见操作方法实例总结【连接、添加、删除、去重、排序等】
2019/06/13 Javascript
详解ES6数组方法find()、findIndex()的总结
2020/05/12 Javascript
JQuery+drag.js上传图片并且实现图片拖曳
2020/11/18 jQuery
Python中你应该知道的一些内置函数
2017/03/31 Python
Python基于FTP模块实现ftp文件上传操作示例
2018/04/23 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
2018/07/25 Python
python正则爬取某段子网站前20页段子(request库)过程解析
2019/08/10 Python
Python3+Selenium+Chrome实现自动填写WPS表单
2020/02/12 Python
pytorch实现seq2seq时对loss进行mask的方式
2020/02/18 Python
Python 去除字符串中指定字符串
2020/03/05 Python
HTML5的革新 结构之美
2011/06/20 HTML / CSS
金智子午JAVA面试题
2015/09/04 面试题
GWT (Google Web Toolkit)有哪些主要的原件组成?
2015/06/08 面试题
计算机应用毕业生自荐信
2013/10/23 职场文书
会计专业应届生求职信
2013/11/24 职场文书
项目资料员岗位职责
2013/12/10 职场文书
成品仓管员岗位职责
2013/12/11 职场文书
初一科学教学反思
2014/01/27 职场文书
出生证明格式
2015/06/15 职场文书