1. 程式人生 > >php緩沖區

php緩沖區

not tar XML mce log 清除 解釋器 clean 初始

我理解的要點:

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刷出,都是由位於隊尾緩沖區塊向上一級緩沖區塊刷出,且區塊裏的內容不是替換,而是疊加。

看例子
echo ob_get_level(),一般情況下輸出:
1
因為php.ini默認設置了output_buffering = 4096,這代表著不管程序裏面怎麽寫,php已經設置了一個緩沖區。

該緩沖區可以手工關閉:

ob_end_clean();
echo ob_get_level();

這時程序輸出:
0
如果再加一條ob_end_clean()就會看到提示:
Notice: ob_end_clean(): failed to delete buffer. No buffer to delete

更改php.ini,修改配置output_buffering = 0,再看echo ob_get_level(),輸出:
0

將配置修改成output_buffering = 4096,恢復初始狀態。

進入例子:

<?php
echo ob_get_level(),‘<br/> ‘;
ob_start(); 
echo ob_get_level(),‘<br/> ‘;
ob_start(); 
echo ob_get_level(),‘<br/> ‘;
?>

輸出:

1
2
3
因為output_buffering = 4096,默認存在一個緩沖區(理解名為”buffer_A”區塊),所以第一次echo ob_get_level()結果為1;
ob_start()開啟了一個緩沖區(理解名為”buffer_B”區塊),這時echo ob_get_level()結果為2.
level有點類似數組元素的下標+1
當ob_start()再開啟一個緩沖區(理解名為”buffer_C”區塊),這時echo ob_get_level()結果為3.

再看例子:

<?php
echo ob_get_level(),‘<br/> ‘;
ob_start(); 
echo ob_get_level(),‘<br/> ‘;
ob_start(); 
echo ob_get_level(),‘<br/> ‘;

ob_end_clean();
echo ob_get_level(),‘<br/> ‘;
?>

結果是
1
2
2
因為output_buffering = 4096,默認存在一個緩沖區(理解名為”buffer_A”區塊),所以第一次echo ob_get_level()結果為1,且該結果是保存在”buffer_A”區塊中;
第一次ob_start()開啟了一個緩沖區(理解名為”buffer_B”區塊),這時echo ob_get_level()結果為2,且該結果是保存在”buffer_B”區塊中。
第二次ob_start()再開啟一個緩沖區(理解名為”buffer_C”區塊),這時echo ob_get_level()結果為3,且該結果是保存在”buffer_C”區塊中
到此為止,所有輸出並沒有直接發送到web服務器。
這時調用ob_end_clean(),將會把”buffer_C”區塊給刪除掉,所以結果3就不存在了
再次echo ob_get_level()時,因為沒有”buffer_C”區塊,所以當前應該是2,且結果保存在”buffer_B”中。
如果把ob_end_clean()改成ob_end_flush()
結果是
1
2
3
2
原理和上面一樣,只是ob_end_flush()並沒有直接把”buffer_C”區塊中的內容直接清除,而是先把區塊中的內容flush到他的上一級緩沖區塊”buffer_B”中了。這時”buffer_B”區塊中的內容變成了"2<br>"."3<br>"。然後再刪除緩沖區塊”buffer_C”

php緩沖區