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