首頁 後端開發 php教程 php深入理解刷新緩衝區函數用法

php深入理解刷新緩衝區函數用法

May 24, 2018 pm 04:26 PM
php 函數 重新整理 深入 理解 緩衝區

有關php的ob_flush()與flush()使用方法

#注意:ob_flush()和flush()這兩個函數一般要一起使用,順序是先ob_flush(),然後flush(),它們的作用是刷新緩衝區。
這裡具體的說下什麼時候要用到刷新緩衝區和為什麼要刷新緩衝區。

一、什麼時候要刷新緩衝區

當程式中用到file_get_contents()和file_put_contens()這兩個函數時,或程式中執行類似的「讀寫」功能或向瀏覽器執行輸出操作時,會用到ob_flush()和flush()來刷新緩衝區。

二、為什麼要刷新緩衝區

用file_get_contents()和file_put_content()為例來解說。

file_get_contents()和file_put_conents()這兩個函數分別執行讀取資料和寫入資料操作,資料是先被讀到記憶體然後在寫入檔案中的,因為讀取的速度比寫入的速度要快,所以當你的資料被讀完的時候不代表資料也寫入完畢,這個時候多讀的內容就會被暫時放到緩衝區中(記憶體),在這裡需要強調一下,其實資料讀取和寫入是兩個非常快的動作哦。

也用一種解釋(當程式向瀏覽器執行輸出操作時),個別web伺服器程序,特別是Win32下的web伺服器程序,在發送結果到瀏覽器之前,仍然會快取腳本的輸出,直到程式結束為止。如果你不想讓程式執行完畢才輸出,那麼你也可以用到ob_flush()和flush()來刷新快取。

其實,flush()還有一種用途,就是在沒結束程式之前就進行輸出,即一個循環還沒結束就可以把部分結果輸出到瀏覽器上,這個效果很類似ajax的異步傳輸效果。
深入理解ob_flush和flush的區別
ob_flush/flush在手冊中的描述, 都是刷新輸出緩衝區, 並且還需要配套使用, 所以會導致很多人迷惑…
其實, 他們兩​​個的操作物件不同, 有些情況下, flush根本不做什麼事情..
ob_*系列函數, 是操作PHP本身的輸出緩衝區.
所以, ob_flush是刷新PHP自身的緩衝區.
而flush, 嚴格來講, 這個只有在PHP做為apache的Module(handler或者filter)安裝的時候, 才有實際作用. 它是刷新WebServer(可以認為特指apache)的緩衝區.
在apache module的sapi下, flush會透過呼叫sapi_module的flush成員函數指標, 間接的呼叫apache的api: ap_rflush刷新apache的輸出緩衝區, 當然手冊中也說了,有一些apache的其他模組, 可能會改變這個動作的結果..
有些Apache的模組,比如mod_gzip,可能會自己進行輸出緩存,這將導致flush()函數產生的結果不會立即被發送到客戶端瀏覽器。
甚至瀏覽器也會在顯示之前,快取接收到的內容。例如 Netscape瀏覽器會在接受到換行或 html 標籤的開頭之前快取內容,並且在接受到 標記之前,不會顯示整個表格。
一些版本的Microsoft Internet Explorer 只有當接受到的256個位元組以後才開始顯示該頁面,所以必鬚髮送一些額外的空格來讓這些瀏覽器顯示頁面內容所以, 正確使用倆者的順序是.先ob_flush, 然後flush,
當然, 在其他sapi下, 不調用flush也可以, 只不過為了保證你代碼的可移植性, 建議配套使用.

buffer --- - flush()

buffer是一個記憶體位址空間,Linux系統預設大小一般為4096(1kb),即一個記憶體頁。主要用於儲存速度不同步的設備或優先順序不同的 設備之間傳辦理資料的區域。透過buffer,可以讓進程這間的相互等待變少。這裡說一個通俗一點的例子,你打開文字編輯器編輯一個文件的時候,你每輸入一個字符,操作系統並不會立即把這個字符直接寫入到磁盤,而是先寫入到buffer,當寫滿了一個buffer的時候,才會把buffer中的資料寫入磁碟,當然當呼叫核心函數flush()的時候,強制要求把buffer中的髒資料寫回磁碟。
同樣的道理,當執行echo,print的時候,輸出並沒有立即透過tcp傳給客戶端瀏覽器顯示, 而是將資料寫入php buffer。 php output_buffering機制,意義在tcp buffer之前,建立了一新的佇列,資料必須經過該佇列。當一個php buffer寫滿的時候,腳本進程會將php buffer中的輸出資料交給系統核心交由tcp傳給瀏覽器顯示。所以,資料會依序寫到這幾個地方echo/pring -> php buffer -> tcp buffer -> browser
php output_buffering --- ob_flush()
#預設情況下,php buffer是開啟的,而且該buffer預設值是4096,即1kb。你可以透過在php.ini設定檔中找到output_buffering配置.當echo,print等輸出使用者資料的時候,輸出資料都會寫入到php output_buffering中,直到output_buffering寫滿,會將這些數據透過tcp傳送給瀏覽器顯示。你也可以透過 ob_start()手動啟動php output_buffering機制,使得即便輸出超過了1kb數據,也不真的把數據交給tcp傳給瀏覽器,因為ob_start()將php buffer空間設定到了足夠大 。只有直到腳本結束,或呼叫ob_end_flush函數,才會把資料傳送給客戶端瀏覽器。

這兩個函數的使用怕是很多人最迷惑的一個問題,手冊上對兩個函數的解釋也語焉不詳,沒有明確的指出它們的區別,似乎二者的功能都是刷新輸出緩存。但在我們文章一開始的程式碼中如果講fush()替換成ob_flush(),程式就再不能正確執行了。顯然,它們是有區別的,否則也手冊中直接說明其中一個是另一個函數的別名即可了,沒必要分別說明。那麼它們的差別到底是什麼呢?
在沒有開啟快取時,腳本輸出的內容都在伺服器端處於等待輸出的狀態 ,flush()可以將等待輸出的內容立即傳送到客戶端。

開啟快取後,腳本輸出的內容存入了輸出快取中 ,這時沒有處於等待輸出狀態的內容,你直接使用flush()不會向客戶端發出任何內容。而ob_flush()的作用就是將本來存在輸出快取中的內容取出來,設定為等待輸出狀態,但不會直接傳送到客戶端 ,這時你就需要先使用ob_flush()再使用flush(),客戶端才能立即獲得腳本的輸出。

一. flush和ob_flush的正確順序,正確應是,先ob_flush再flush,如下:
ob_flush();
flush();
如果Web伺服器的作業系統是windows系統,那順序顛倒或不使用ob_flush()也不會出現問題。 [有待求證 ] 但是在Linux系統上就無法刷新輸出緩衝。
output buffering函數
1.bool ob_start ([ callback $output_callback [, int $chunk_size [, bool $erase ]]] )
啟動output_buffering機制。一旦激活,腳本輸出不再直接出給瀏覽器,而是先暫時寫入php buffer記憶體區域。
php預設開啟output_buffering機制,只不過,透過呼叫ob_start()函式資料output_buffering值擴展到足夠 大 。也可以指定$chunk_size來指定output_buffering的值。 $chunk_size預設值是0,表示直到腳本運行結束,php buffer中的資料才會傳送到瀏覽器。如果你設定了$chunk_size的大小 ,表示只要buffer中資料長度達到了該值,就會將buffer中 的資料傳送給瀏覽器。
當然,你可以透過指定$ouput_callback,來處理buffer中的資料。例如函數ob_gzhandler,將buffer中的資料壓縮後再傳送給瀏覽器。
第三個參數:是否擦除緩存,可選,預設是true,如果設定為false,則在腳本執行結束前,快取都不會被清除。
2.ob_get_contents
取得一份php buffer中的資料拷貝。值得注意的是,你應該在ob_end_clean()函數呼叫前呼叫該函數,否則ob_get_contents()傳回一個空字元中。
可以使用ob_get_contents()以字串形式取得服務端快取的數據,
使用ob_end_flush()則會輸出被快取的數據,並關閉快取。
而使用ob_end_clean()則會靜默的清除服務端快取的數據,而不會有任何資料或其他行為。
服務端的快取是堆疊起來的,也就是說你在開啟了ob_start()後,關閉之前,在其內部還 可以開啟另外一個快取ob_start()。
不過你也要務必保證關閉快取的操作和開啟快取的操作數量一樣多。
ob_start() 可以指定一個回呼函數來處理快取資料,如果一個ob_start()內部嵌套了另一個ob_start(),我們假定,外層的ob_start(),編號是A,內層的ob_start()編號是B,它們各自製定了一個回呼函數分別是functionA和functionB,那麼在快取B中的資料輸出時,它會先輩funcitonB回呼函數處理,再交給外層的functionA回呼函數處理,之後才能輸出到客戶端。
另外,手冊說,對於某些web伺服器,例如apache,在使用回調函數有可能會改變程式目前的工作目錄,解決方法是在回呼函數中自行手動把工作目錄修改回來,用chdir函數,這點似乎不常遇到,遇到的時候記得去查手冊吧。
3.ob_end_flush與ob_end_clean
這二個函數有點相似,都會關閉ouptu_buffering機制。但不同的是,ob_end_flush只是把php buffer中的資料衝(flush/send)到客戶端瀏覽器,而ob_clean_clean將php bufeer中的資料清空(erase),但不傳送給客戶端瀏覽器。
ob_end_flush呼叫之前 ,php buffer中的資料依然存在,ob_get_contents()依然可以取得php buffer中的資料拷貝。

而ob_end_flush()呼叫之後 ob_get_contents()取到的是空字串,同時瀏覽器也接收不到輸出,也就是沒有任何輸出。

可以使用ob_get_contents()以字串形式取得服務端快取的數據,使用ob_end_flush()則會輸出被快取的數據,並關閉快取。
而使用ob_end_clean()則會靜默的清除服務端快取的數據,而不會有任何資料或其他行為。

以上是php深入理解刷新緩衝區函數用法的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

<🎜>:泡泡膠模擬器無窮大 - 如何獲取和使用皇家鑰匙
3 週前 By 尊渡假赌尊渡假赌尊渡假赌
北端:融合系統,解釋
3 週前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

熱門話題

Java教學
1664
14
CakePHP 教程
1423
52
Laravel 教程
1318
25
PHP教程
1269
29
C# 教程
1248
24
在PHP API中說明JSON Web令牌(JWT)及其用例。 在PHP API中說明JSON Web令牌(JWT)及其用例。 Apr 05, 2025 am 12:04 AM

JWT是一種基於JSON的開放標準,用於在各方之間安全地傳輸信息,主要用於身份驗證和信息交換。 1.JWT由Header、Payload和Signature三部分組成。 2.JWT的工作原理包括生成JWT、驗證JWT和解析Payload三個步驟。 3.在PHP中使用JWT進行身份驗證時,可以生成和驗證JWT,並在高級用法中包含用戶角色和權限信息。 4.常見錯誤包括簽名驗證失敗、令牌過期和Payload過大,調試技巧包括使用調試工具和日誌記錄。 5.性能優化和最佳實踐包括使用合適的簽名算法、合理設置有效期、

php程序在字符串中計數元音 php程序在字符串中計數元音 Feb 07, 2025 pm 12:12 PM

字符串是由字符組成的序列,包括字母、數字和符號。本教程將學習如何使用不同的方法在PHP中計算給定字符串中元音的數量。英語中的元音是a、e、i、o、u,它們可以是大寫或小寫。 什麼是元音? 元音是代表特定語音的字母字符。英語中共有五個元音,包括大寫和小寫: a, e, i, o, u 示例 1 輸入:字符串 = "Tutorialspoint" 輸出:6 解釋 字符串 "Tutorialspoint" 中的元音是 u、o、i、a、o、i。總共有 6 個元

解釋PHP中的晚期靜態綁定(靜態::)。 解釋PHP中的晚期靜態綁定(靜態::)。 Apr 03, 2025 am 12:04 AM

靜態綁定(static::)在PHP中實現晚期靜態綁定(LSB),允許在靜態上下文中引用調用類而非定義類。 1)解析過程在運行時進行,2)在繼承關係中向上查找調用類,3)可能帶來性能開銷。

什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? 什麼是PHP魔術方法(__ -construct,__destruct,__call,__get,__ set等)並提供用例? Apr 03, 2025 am 12:03 AM

PHP的魔法方法有哪些? PHP的魔法方法包括:1.\_\_construct,用於初始化對象;2.\_\_destruct,用於清理資源;3.\_\_call,處理不存在的方法調用;4.\_\_get,實現動態屬性訪問;5.\_\_set,實現動態屬性設置。這些方法在特定情況下自動調用,提升代碼的靈活性和效率。

PHP和Python:比較兩種流行的編程語言 PHP和Python:比較兩種流行的編程語言 Apr 14, 2025 am 12:13 AM

PHP和Python各有優勢,選擇依據項目需求。 1.PHP適合web開發,尤其快速開發和維護網站。 2.Python適用於數據科學、機器學習和人工智能,語法簡潔,適合初學者。

PHP行動:現實世界中的示例和應用程序 PHP行動:現實世界中的示例和應用程序 Apr 14, 2025 am 12:19 AM

PHP在電子商務、內容管理系統和API開發中廣泛應用。 1)電子商務:用於購物車功能和支付處理。 2)內容管理系統:用於動態內容生成和用戶管理。 3)API開發:用於RESTfulAPI開發和API安全性。通過性能優化和最佳實踐,PHP應用的效率和可維護性得以提升。

PHP:網絡開發的關鍵語言 PHP:網絡開發的關鍵語言 Apr 13, 2025 am 12:08 AM

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP的持久相關性:它還活著嗎? PHP的持久相關性:它還活著嗎? Apr 14, 2025 am 12:12 AM

PHP仍然具有活力,其在現代編程領域中依然佔據重要地位。 1)PHP的簡單易學和強大社區支持使其在Web開發中廣泛應用;2)其靈活性和穩定性使其在處理Web表單、數據庫操作和文件處理等方面表現出色;3)PHP不斷進化和優化,適用於初學者和經驗豐富的開發者。

See all articles