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

4次阅读

共计 2364 个字符,预计需要花费 6 分钟才能阅读完成。

一、概念

在 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…

正文完
 0