首頁 >後端開發 >php教程 >PHP 輸出緩衝控制詳解

PHP 輸出緩衝控制詳解

墨辰丷
墨辰丷原創
2018-06-01 14:47:411559瀏覽

本文主要介紹PHP 輸出緩衝控制,這裡提供了詳細的相關資料及簡單範例程式碼,幫助大家學習參考,有興趣的夥伴可以參考下

  php 緩衝簡介

      其實我對php ob 系列印象還是很模糊,具體怎麼玩的,還不是很了解,平時curd,確實對這些內容沒有深入。作為phper 甚是慚愧。網路上搜了一通,互相copy,程式碼運作不能出現作者所描述現象,本文良心出品,程式碼都是作者運作過。

   當執行輸出的時候,例如 echo,print。輸出並沒有立即送給 web server, 而是將資料寫入 php buffer。 php output_buffering 機制好處當然提升效能。其實 php 檔案最後在瀏覽器上顯示,走過3個緩衝階段: php buffer=》web server buffer=》browser buffer。最後顯示到瀏覽器

  預設情況下,php buffer 是開啟的,而且該 buffer 預設值是4096,即4 kb。你可以透過在php.ini設定檔中找到output_buffering配置。 buffer是一個記憶體位址空間,Linux系統預設大小一般為4096(4kb),即一個記憶體頁。主要用於儲存速度不同步的設備或優先順序不同的設備之間傳辦理資料的區域。透過buffer,可以讓進程這間的相互等待變少。這裡說一個通俗一點的例子,你打開文字編輯器編輯一個文件的時候,你每輸入一個字符,操作系統並不會立即把這個字符直接寫入到磁盤,而是先寫入到buffer,當寫滿了一個buffer的時候,才會把buffer中的資料寫入磁碟,當然當呼叫核心函數flush()的時候,強制要求把buffer中的髒資料寫回磁碟。

  舉例

<?php
echo "南无阿弥陀佛<br>";
header("content-type:text/html;charset=&#39;utf-8&#39;");
echo "真善忍好!";
//output
//南无阿弥陀佛
//真善忍好

#header()必須在任何實際輸出之前調用,但是我們程式已經輸出了,卻正常運作。在看下面的程式碼:

<?phpecho "南无阿弥陀佛<br>";
ob_flush();
header("content-type:text/html;charset=&#39;utf-8&#39;");
echo "真善忍好!";
//output
//南无阿弥陀佛
//Cannot modify header information - headers already sent by (output started at E:\php\test.php:3)
//真善忍好

上面程式說明程式並沒有立即輸出,而當呼叫ob_flush 函數的時候才刷新緩衝,輸出。

  ob_flush() 與flush()

ob_flush() , flush() 函數php 手冊上都有詳細的說明,你可以去查閱。二者的差異是:

ob_flush() 是刷新PHP自身的緩衝區

flush()是它是刷新WebServer 伺服器的緩衝。輸出到瀏覽器。 但是會出現下面的情況:

  1. 個別web伺服器程序,特別是Win32下的web伺服器程序,在發送結果到瀏覽器之前,仍然會快取腳本的輸出,直到程式結束為止。

  2. 有些Apache的模組,例如mod_gzip,可能會自己進行輸出緩存,這將導致flush()函數產生的結果不會立即被傳送到客戶端瀏覽器。

  3. 甚至瀏覽器也會在顯示之前,快取接收到的內容。例如 Netscape 瀏覽器會在接受到換行或 html 標籤的開頭之前快取內容,並且在接受到 f16b1740fad44fb09bfe928bcc527e08 標記之前,不會顯示整個表格。

  4. 某些版本的 Microsoft Internet Explorer 只有在接受到的256個位元組以後才開始顯示該頁面,所以必須傳送一些額外的空格來讓這些瀏覽器顯示頁面內容。

 例如:

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo &#39;佛法无边&#39;."<BR>";
ob_flush();
flush();
sleep(1);
echo &#39;法轮常转&#39;;

//output

上面的程式碼在chrome 瀏覽器上面是一行一行的輸出,在ie系列的瀏覽器則是全部輸出。其實就是上面的 第四條一些瀏覽器只有當接收256個字元才開始顯示。把上面的程式碼改成下面形式:

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo str_pad(&#39;&#39;,240)."\n"; 
echo &#39;佛法无边&#39;."<BR>";
ob_flush();
flush();
sleep(1);
echo &#39;法轮常转&#39;;

//output

這樣就會一行一行輸出,因為超過256個字元。

  ob 其他函數說明

#1.ob_end_flush 與ob_end_clean

  end 的顧名思義就結束,關閉緩衝區,都是關閉輸出緩衝,一個是輸出緩衝區,一個是清除。例如

<?php
/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo &#39;before&#39;;
ob_end_clean();
echo str_pad(&#39;&#39;,4096)."\n";
for ($i=10; $i>0; $i--) 
{ 
 echo $i;
 sleep(1);
}

上述程式碼就是一下輸出全部內容,而不是一個一個輸出。 ob_end_clean() 不是關閉了緩衝了?怎麼不是一個輸出呢,其實我們上面也說了,php 不是直接輸出給瀏覽器,而是 web server。雖然php 沒有了 緩衝。但是web server 還是有的。所以下面程式碼:

/**
Server:LightTPD/1.4.28 (Win32)
X-Powered-By:PHP/5.3.27
*/
echo &#39;before&#39;;
ob_end_clean();
echo str_pad(&#39;&#39;,4096)."\n";
for ($i=10; $i>0; $i--) 
{ 
 flush();
 echo $i;
 sleep(1);
}

加上flush(),就會一行一行輸出。如果把ob_end_clean 換成 ob_end_flush  會把 before 輸出來。

其他函數 可參考手冊,比較簡單。

  總結

php 腳本到瀏覽器,要經過  php buffer=》web server buffer=》browser buffer。最後顯示到瀏覽器。缺一不可。所以我們要 ob_flush 和  flush 以及加上  echo str_pad('',4096) 才能除錯出你想要的效果。

總結:以上就是這篇文章的全部內容,希望能對大家的學習有所幫助。

相關推薦:

PHP實作的登錄,註冊及密碼修改功能

PHP 匿名函數與注意事項詳解

PHP中call_user_func_array回呼函數的用法

以上是PHP 輸出緩衝控制詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn