php缓冲机制及嵌套级别 ob_get_level

ob_get_level(void):int

  • 返回嵌套的输出缓冲处理程序的级别;或者是,如果输出缓冲区不起作用,返回零。

php.ini中配置缓冲

在php的配置文件php.ini中有以下这项配置 output_buffering ,php.ini默认设置了output_buffering = 4096,php已经设置了一个缓冲区。

如果php.ini 中打开了此项: echo,print 后的输出顺序就是-> php output_buffring -> server buffering -> browser buffering -> browser display;

如果未打开php输出缓存: echo,print 后的输出顺序就是-> server buffering -> browser buffering -> browser display.

如果 php.ini 开启了缓存,则 ob_get_level() 得到的值会是1,相当于都执行了一次ob_start(),配置output_buffering = 0,嵌套级别的值会为0。

如果总是希望在脚本的开头有一个输出缓冲区,则可以使用

if (!ob_get_level()) ob_start();

在脚本的开头这样写,相当于可以关闭 php.ini 中设置的缓存区

缓存嵌套级别的理解

输出缓冲区处理函数的作用有点类似堆栈,临时放入一个存储空间中,对内容进行处理。类似队列一样,但是不是先进先出,而是先开后关,缓存区关闭的顺序是从下到上

ob_start() 每执行一次,就会开启一个新的缓存区。

先看个例子:

// php.ini中开启了缓存区,相当于都已执行一次 ob_start() (理解名为 buffer_A 区块)
echo '(buffer_A)'; //缓存 buffer_A 区 保存了下面的所有输出
echo ob_get_level(); 	#输出1

ob_start();		#开启一个缓存区(理解名为 buffer_B 区块)
echo '(buffer_B)'; //缓存 buffer_B 区 保存了下面的所有输出(不包括A区的内容)
echo ob_get_level(); 	#输出2

ob_start();		#开启一个缓存区(理解名为 buffer_C 区块)
echo '(buffer_C)'; //缓存 buffer_C 区 保存了下面的所有输出(不包括 A&B 区的内容)
echo ob_get_level();	#输出3

echo "<br>---------------------<br>";

//第1次获取输出缓存区的内容是最后一个缓冲区的内容:输出  buffer_C 区范围下的内容
//echo ob_get_contents(); # 输出 3(buffer_C)

//第1次关闭的缓冲区是最后一个缓存区:buffer_C
ob_end_flush();		#关闭缓存区(buffer_C )

//关闭1个缓存区后,第二次获取缓存区的内容:输出的是 buffer_B 区 范围下的内容,
//echo ob_get_contents(); # 输出 2(buffer_B)3(buffer_C)

//第2次关闭的缓冲区:buffer_B
ob_end_flush();

//关闭2个缓存区后,第三次获取缓存区的内容:输出的是 buffer_A 区 范围下的内容,
//echo ob_get_contents();  # 输出 (buffer_A)1(buffer_B)2(buffer_C)3

//第3次关闭的缓冲区:buffer_A,此时所有的缓冲区都被清了
ob_end_flush();
echo ob_get_contents(); # 没有内容输出

通过 ob_get_contents() 每次获取到的缓存区的内容可得到,每个缓冲区保存的内容都是在他下面范围的内容。
这个“下面”怎么理解,如例中:buffer_A 区保存A,B,C 这3区的内容,buffer_B 区保存的是B,C 这2区的内容,buffer_C 区保存的是 C 这1区的内容。

ob_end_flush()每次关闭都是后面的缓冲区,关闭的顺序是从下到上的关闭,也是先开后关,后开先关,就如排队一样,start 开启时是按照顺序开启,关闭时是从队伍后面开始关闭。
如例子,最先关闭的是 C区,然后 B 区,最后 A 区 。(start开启缓冲区是进队:A,B,C ,end关闭缓存区是出队: C,B,A)

理解好每个缓存区保存的是“所属下面的内容”,第一次开启的缓存区是最顶级的,下面所有子级的内容都在上游的缓存区中。

理解要点

1、所有缓冲区控制是在一个PHP执行进程中发生的。如:你打开n个demo.php,他们之间开启和关闭缓冲是互不影响的。
2、output_buffering在程序中用ini_set是不能生效的。
3、所有缓冲区数据,如果没有手工flush刷出,则在程序结束会被解释器刷出。
4、关于嵌套级别:当顺序开启多个ob_start()时,会相应开启多个缓冲区。可以理解成队列,队伍成员是ob_start()开启的缓冲区块,而ob_get_level()可理解成当前队伍最末尾的缓冲块的序列号。
5、每次echo,print输出的内容都是针对队尾的缓冲区块进行的。
6、每次ob[end][flush|clean]函数也都是针对队尾缓冲区块进行的。
7、每次执行flush刷出,都是由位于队尾缓冲区块向上一级缓冲区块刷出,且区块里的内容不是替换,而是叠加。

posted on 2020-04-23 11:07  追风的浪子  阅读(98)  评论(0编辑  收藏

导航