摘要:默認(rèn)為是一個回調(diào)函數(shù),將腳本的所有輸出,用所定義的函數(shù)進(jìn)行處理。在輸出緩沖區(qū)的回調(diào)函數(shù)中使用這些函數(shù),會導(dǎo)致未定義的錯誤。
簡介
PHP有輸出時,可以用輸出控制函數(shù)來控制輸出
緩沖階段ob_start(),將內(nèi)部緩沖區(qū)(buffer)打開。當(dāng)PHP遇到echo,printf等輸出語句時, PHP就會將要輸出的數(shù)據(jù)放入緩沖區(qū)(buffer)中,等待輸出。而只有當(dāng)緩沖區(qū)滿了或者php運行完畢,才將數(shù)據(jù)輸出去。輸出字節(jié)離開PHP緩沖區(qū)進(jìn)去Apache緩沖區(qū)或者Nginx緩沖區(qū)(fast-cgi),之后進(jìn)入瀏覽器緩沖區(qū)。如下所示:
echo,print -> php buffer -> web server buffer(apache緩沖區(qū),fast-cgi緩沖區(qū)) -> browser buffer
php.ini的配置項下面這些函數(shù)的行為受php.ini中的設(shè)置影響。
1.output_buffering
設(shè)置為 On 時,打開內(nèi)部緩沖區(qū)(buffer)
設(shè)置為 Off 時,關(guān)閉內(nèi)部緩沖區(qū)(buffer)
設(shè)置為數(shù)字時, 限制輸出緩沖區(qū)的最大值
在php.ini里,output_buffering=4096是默認(rèn)開啟的。而此時使用ini_set()去改變output_buffering的值, 無法生效。因為輸出緩沖區(qū)層在php程序啟動的時候,就已經(jīng)打開了。所以只能通過編輯php.ini改變其初始值或者是在執(zhí)行PHP程序的時候使用-d選項才能改變它們的值。
2.output_handler
默認(rèn)為NULL
是一個回調(diào)函數(shù),將腳本的所有輸出,用所定義的函數(shù)進(jìn)行處理。類似與ob_start($output_callback)。
$output_callback:
ob_gzhandler : 使用ext/zlib壓縮輸出
mb_output_handler : 使用ext/mbstring轉(zhuǎn)換字符編碼
ob_iconv_handler : 使用ext/iconv轉(zhuǎn)換字符編碼
ob_tidyhandler : 使用ext/tidy整理輸出的HTML文本
ob_[inflate/deflate]_handler : 使用ext/http壓縮輸出
ob_etaghandler : 使用ext/http自動生成HTTP的Etag
3.implicit_flush
設(shè)置為 On 時,打開絕對刷送。
PHP緩沖區(qū)層發(fā)送數(shù)據(jù)到web server buffer,Apache自動刷新輸出緩沖區(qū),不需要等待刷新指令,直接就把輸出返回到browser buffer
設(shè)置為 Off 時,關(guān)閉絕對刷送。
不自動刷新apache緩沖區(qū),接受到數(shù)據(jù)后,等待刷新指令
在php.ini里,implicit_flush=Off是默認(rèn)關(guān)閉的。如果想要刷新Apache緩沖區(qū),使用PHP的flush()函數(shù)手動刷新?;蛘哒{(diào)用ob_implicit_flush()(隱式刷送)函數(shù)。
ob_*系列函數(shù) ob_flush和flush區(qū)別使用的時候我們經(jīng)常一起使用
if (ob_get_level() == 0) ob_start(); for ($i = 0; $i<10; $i++){ echo "
Line to show."; echo str_pad("",4096)." "; ob_flush(); flush(); sleep(2); } echo "Done."; ob_end_flush();
但是ob_*系列的函數(shù)是操作php buffer,而flush則是操作web server buffer(活著特指上面所提到的Apache緩沖區(qū))。
應(yīng)用場景1.首先肯定是提高性能,減少響應(yīng)次數(shù)
2.修改http頭信息
我們輸出消息到頁面表示請求和響應(yīng)已經(jīng)完成了,是不能再發(fā)送http頭信息了。但是使用緩沖區(qū)就不一樣了
ob_start(); echo "Hello "; setcookie("cookiename", "cookiedata"); ob_end_flush();
在上面的例子中,echo函數(shù)的輸出將一直被保存在輸出緩沖區(qū)中直到調(diào)用 ob_end_flush() 。同時,對setcookie()的調(diào)用也成功存儲了一個cookie,而不會引起錯誤。
3.避免內(nèi)存限制
對于大文件來說, 開啟PHP緩沖區(qū), 一段一段的讀取數(shù)據(jù)到瀏覽器,避免用戶等待,也避免一次讀取數(shù)據(jù)讀取耗盡內(nèi)存。
4.靜態(tài)文件緩存
使用緩沖區(qū)生成靜態(tài)html文件
ob_start("ob_gzhandler"); $content = ob_get_contents(); // 打開文件 $file = fopen("./index.html", "w"); // 將緩沖區(qū)中的內(nèi)容寫入文件 fwrite($file, $content); fclose($file); ob_end_clean();
5.處理輸出的內(nèi)容
eg:進(jìn)行g(shù)zip壓縮,進(jìn)行簡繁轉(zhuǎn)換,或者進(jìn)行一些字符串替換
參考資料:tips:不要在輸出緩沖區(qū)回調(diào)函數(shù)內(nèi)調(diào)用任何緩沖區(qū)相關(guān)的函數(shù),也不要在回調(diào)函數(shù)中輸出任何東西。是因為有些PHP的內(nèi)部函數(shù)也使用了輸出緩沖區(qū),它們會疊加到其他的緩沖區(qū)上,這些函數(shù)會填滿自己的緩沖區(qū)然后刷新,或者是返回里面的內(nèi)容。eg:print_r()、highlight_file()和highlight_file::handle()等。在輸出緩沖區(qū)的回調(diào)函數(shù)中使用這些函數(shù),會導(dǎo)致未定義的錯誤。
[ 1 ] : 深入理解php的輸出緩沖區(qū)(output buffer)
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/22871.html
摘要:的部分是基于以及協(xié)議的。例如父進(jìn)程向中寫入子進(jìn)程從中讀取子進(jìn)程向中寫入父進(jìn)程從中讀取。默認(rèn)使用對進(jìn)程進(jìn)行分配交給對應(yīng)的線程進(jìn)行監(jiān)聽線程收到某個進(jìn)程的數(shù)據(jù)后會進(jìn)行處理值得注意的是這個線程可能并不是發(fā)送請求的那個線程。 作者:施洪寶 一. 基礎(chǔ)知識 1.1 swoole swoole是面向生產(chǎn)環(huán)境的php異步網(wǎng)絡(luò)通信引擎, php開發(fā)人員可以利用swoole開發(fā)出高性能的server服務(wù)。...
閱讀 727·2021-11-23 09:51
閱讀 3619·2021-10-11 10:58
閱讀 15972·2021-09-29 09:47
閱讀 3703·2021-09-01 11:42
閱讀 1370·2019-08-29 16:43
閱讀 1890·2019-08-29 15:37
閱讀 2184·2019-08-29 12:56
閱讀 1790·2019-08-28 18:21