zoukankan      html  css  js  c++  java
  • 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刷出,都是由位于队尾缓冲区块向上一级缓冲区块刷出,且区块里的内容不是替换,而是叠加。
    
  • 相关阅读:
    字符串翻转
    windows套接字相关函数
    Windows多线程同步系列之一-----互斥对象
    Dos命令---ipconfig
    windows多线程没那么难
    CreateThread简单那多线程编程
    TCP/IP协议详解概述
    正则表达式小试牛刀--匹配我的csdn博文标题
    wireshark----教你如何抓包
    HDU1385 (Floyd记录路径)
  • 原文地址:https://www.cnblogs.com/echojson/p/12759346.html
Copyright © 2011-2022 走看看