成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

PHP的輸出緩沖區(qū)

cyixlq / 2104人閱讀

摘要:什么是緩沖區(qū)簡單而言緩沖區(qū)的作用就是把輸入或者輸出的內(nèi)容先放進(jìn)內(nèi)存而不顯示或者讀取至于為什么要有緩沖區(qū)這是一個很廣泛的問題如果有興趣可以在網(wǎng)山找下資料其實緩沖區(qū)最本質(zhì)的作用就是協(xié)調(diào)高速和相對緩慢的設(shè)備磁盤等的運(yùn)作在執(zhí)行的時候在什么地方有用到

什么是緩沖區(qū)?
簡單而言,緩沖區(qū)的作用就是,把輸入或者輸出的內(nèi)容先放進(jìn)內(nèi)存,而不顯示或者讀取.至于為什么要有緩沖區(qū),這是一個很廣泛的問題,如果有興趣,可以在網(wǎng)山找下資料.
其實緩沖區(qū)最本質(zhì)的作用就是,協(xié)調(diào)高速CPU和相對緩慢的IO設(shè)備(磁盤等)的運(yùn)作.

PHP在執(zhí)行的時候,在什么地方有用到緩沖區(qū)?
想要了解PHP的緩沖區(qū),就要知道執(zhí)行PHP的時候,緩沖區(qū)被設(shè)置到了什么地方.
當(dāng)執(zhí)行PHP的時候,如果碰到了echo print_r之類的會輸出數(shù)據(jù)的代碼,PHP就會將要輸出的數(shù)據(jù)放到PHP自身的緩沖區(qū),等待輸出.
當(dāng)PHP自身的緩沖區(qū)接到指令,指示要輸出緩沖區(qū)的內(nèi)容時,將會把緩沖區(qū)內(nèi)的數(shù)據(jù)輸出到apache上, apache接受到PHP輸出的數(shù)據(jù),然后再把該數(shù)據(jù)存在到apache自身的緩沖區(qū)內(nèi),等到輸出
當(dāng)apache接受到指令,只是要輸出緩沖區(qū)的內(nèi)容時, 將會把緩沖區(qū)的內(nèi)容輸出,返回到瀏覽器.

由此可見,PHP要輸出數(shù)據(jù)的時候,將會經(jīng)過兩個緩沖區(qū)(先是自身的,然后是apache的),再返回到瀏覽器.

緩沖區(qū)在PHP中起到什么作用?
1.最常見的就是在使用header函數(shù)之前,就已經(jīng)輸出了某些數(shù)據(jù),這樣會導(dǎo)致某些錯誤,例如 Cannot modify header information – headers already sent by;

echo "this is test";
header("LOCATION http://www.baidu.com");

出現(xiàn)這個錯誤的原因是, 在header之前已經(jīng)輸出了某些數(shù)據(jù),而輸出這些數(shù)據(jù)的同時, apache將會同時發(fā)送一個響應(yīng)狀態(tài)到瀏覽器上(既然有輸出,即這個請求是有效的),而其后你又再次使用header函數(shù)
發(fā)送http頭,則會返回這個錯誤,錯誤的意思是:HTTP頭已經(jīng)發(fā)送出去了,你不能對他再做修改.
為什么使用緩沖區(qū)可以避免這個錯誤呢?
因為header函數(shù)是不受緩沖區(qū)影響的,當(dāng)一碰到header函數(shù)的時候,PHP馬上執(zhí)行apache發(fā)送這一個http頭都瀏覽器.
而輸出的數(shù)據(jù)PHP打開輸出緩沖區(qū)后, 這些數(shù)據(jù)將會存放在緩沖區(qū),等待輸出.這樣就可以避免了之前所發(fā)生的錯誤.
2.通過PHP寫文件下載程序的時候.
為了讓文件下載更安全,同時提高更多的可控性,很多朋友都喜歡用PHP寫文件下載頁面.其原理很簡單,就是通過fwrite把文件內(nèi)容讀出并顯示,然后通過header來發(fā)送HTTP頭,讓瀏覽器知道這是一個附件,這樣
就可以達(dá)到提供下載的效果.
如果用上面的辦法提供下載頁面,會碰到一個效率問題,如果一個文件很大,假設(shè)為100M,那么在不開啟緩沖區(qū)輸出的情況下,必須要把100M數(shù)據(jù)全部讀出,然后一次返回到頁面上,如果這樣做,用戶將會在所有數(shù)據(jù)讀完
之后才會得到響應(yīng),降低了用戶體驗感.
如果開啟了輸出緩沖區(qū),當(dāng)PHP程序讀完文件的某一段,然后馬上輸出到apache,然后讓apache馬上返回到瀏覽器,這樣就可以減少用戶等待時間.那后面的數(shù)據(jù)怎么辦呢?我們可以寫一個while循環(huán),一直一段一段地讀取文件
每讀一段,就馬上輸出,直到把文件全部輸出為止,這樣瀏覽器就可以持續(xù)地接受到數(shù)據(jù),而不必等到所有文件讀取完畢.

另外,該做法還解決了另外一個很嚴(yán)重的問題.例如一個文件是100M,如果不開啟緩沖區(qū)的情況下,則需要把100M文件全部讀入內(nèi)存,然后再輸出.但是,如果PHP程序做了內(nèi)存限制呢?為了保證服務(wù)器的穩(wěn)定,管理員通常會把PHP的執(zhí)行
內(nèi)存設(shè)一個限制(通過php.ini總的memory_limit, 其默認(rèn)值是8M), 也就是每個PHP程序使用的內(nèi)存不能使用超過這個值的內(nèi)存. 假設(shè)該值為8M,而要讀入的文件是100M,根本就沒有足夠的內(nèi)存來讀入該文件.這個時候,我們就需要用到上面的
辦法來解決這個問題,每次只讀某一段,這樣就可以避免了內(nèi)存的限制
3.靜態(tài)文件緩存
現(xiàn)在很多公司有這么一個需求, 就是某一個頁面在第一次訪問的時候,會執(zhí)行PHP,然后把顯示的內(nèi)容返回到瀏覽器,同時需要把這次顯示的內(nèi)容保存到服務(wù)器上,這樣下次訪問的時候,就直接把保存在服務(wù)器上的文件直接顯示,而不需要通過PHP來做操作
這就是所謂的”靜態(tài)頁面緩存”.那怎么樣才能做到把內(nèi)容返回到瀏覽器的同時把數(shù)據(jù)保存到服務(wù)器上呢?這就要用到輸出緩沖區(qū)了.

ob_start();
echo "aaa";
$string = ob_get_contents();
file_put_contents("a.html", $string);
ob_flush();
flush();

與輸出緩沖區(qū)有關(guān)的配置
在PHP.INI中,有兩個跟緩沖區(qū)緊密相關(guān)的配置項
1.output_buffering
該配置直接影響的是php本身的緩沖區(qū),有3種配置參數(shù).on/off/xK(x為某個整型數(shù)值);
on - 開啟緩沖區(qū)
off - 關(guān)閉緩沖區(qū)
256k - 開啟緩沖區(qū),而且當(dāng)緩沖區(qū)的內(nèi)容超過256k的時候,自動刷新緩沖區(qū)(把數(shù)據(jù)發(fā)送到apache);

2.implicit_flush
該配置直接影響apache的緩沖區(qū),有2種配置參數(shù). on/off
on - 自動刷新apache緩沖區(qū),也就是,當(dāng)php發(fā)送數(shù)據(jù)到apache的緩沖區(qū)的時候,不需要等待其他指令,直接就把輸出返回到瀏覽器
off - 不自動刷新apache緩沖區(qū),接受到數(shù)據(jù)后,等待刷新指令

與緩沖區(qū)有關(guān)的函數(shù)
1.ob_implicit_flush
作用和implicit_flush一樣,是否自動刷新apache的緩沖區(qū)
2.flush
作用是發(fā)送指令到apache,讓apache刷新自身的輸出緩沖區(qū).
3.ob_start
打開輸出緩沖區(qū),無論php.ini的文件如何配置,如果使用該函數(shù),即使output_buffering設(shè)置成off,也會打開輸出緩沖區(qū)
ob_start函數(shù)還接受一個參數(shù),該參數(shù)是一個函數(shù)的回調(diào),意思是,在輸入緩沖區(qū)內(nèi)容之前,需要使用調(diào)用傳遞進(jìn)來的參數(shù)把緩沖區(qū)的內(nèi)容處理一次,再放入緩沖區(qū)內(nèi)
4.ob_flush
指示php本身刷新自身的緩沖區(qū),把數(shù)據(jù)發(fā)送到apache
5.ob_clean
清除php緩沖區(qū)里面的內(nèi)容
6.ob_end_clean
清除php緩沖區(qū)內(nèi)的內(nèi)容,并且關(guān)閉輸出緩沖區(qū)
7.ob_end_flush
把php自身的緩沖區(qū)里的內(nèi)容發(fā)送到apache,并把清除自身緩沖區(qū)內(nèi)的內(nèi)容
8.ob_get_clean
獲取緩沖區(qū)的內(nèi)容之后,清除緩沖區(qū).
9.ob_get_contents
獲取輸出緩沖區(qū)里的內(nèi)容
10.ob_get_flush
獲取緩沖區(qū)里的內(nèi)容,并且把這些內(nèi)容發(fā)送到apache
11.ob_get_length
獲取緩沖區(qū)里內(nèi)容的長度
12.ob_list_handlers
獲取運(yùn)行ob_start時,所回調(diào)的函數(shù)名稱, 例如:
ob_start(‘ob_gzhandler’);
print_r(ob_list_handlers);
將打印出ob_gzhandler;
13.ob_gzhandler
該函數(shù)的作用是作為ob_start的回調(diào)參數(shù), 在緩沖區(qū)刷新之前,會調(diào)用該函數(shù)對數(shù)據(jù)進(jìn)行到底gzip或者deflate壓縮.這個函數(shù)需要zlib擴(kuò)展的支持.

使用緩沖區(qū)的相關(guān)內(nèi)容
1.ob_flush和flush的次序關(guān)系.上面的分析可以看出,ob_flush是和php自身相關(guān)的,而flush操作的是apache的緩沖區(qū),所有我們在使用這兩個函數(shù)的時候,需要先執(zhí)行ob_flush,
再執(zhí)行flush,因為我們需要先把數(shù)據(jù)從PHP上發(fā)送到apache,然后再由apache返回到瀏覽器.如果php還沒有把數(shù)據(jù)刷新到apache,就調(diào)用了flush,則apache無任何數(shù)據(jù)返回到瀏覽器.

2.有的瀏覽器,如果接受到的字符太少,則不會把數(shù)據(jù)顯示出來,例如老版的IE(必須要大于256k才顯示).這樣就會造成一個疑問, 明明在php和apache都進(jìn)行了刷新緩沖區(qū)的操作,但是瀏覽器就是沒有出現(xiàn)自己想要的數(shù)據(jù),也許就是這個原因造成的.所以才測試的時候,可以在輸出數(shù)據(jù)的后面加上多個空格,以填滿數(shù)據(jù),確定不會瀏覽器造成這類詭異的問題.

3.有些webserver,他自身的輸出緩沖區(qū)會有一些限制,比如nginx,他有一個配置fastcgi_buffer_size 4k, 就是是表明,當(dāng)自身的輸出緩沖區(qū)的內(nèi)容達(dá)到4K才會刷新,所以為了保證內(nèi)容的數(shù)據(jù),可以添加以下代碼,保證內(nèi)容長度


4.在apache中,如果你開啟了mod_gzip的壓縮模塊,這樣可能會導(dǎo)致你的flush函數(shù)刷新不成功,其原因是,mod_gzip有自己的輸出緩沖區(qū),當(dāng)php執(zhí)行了flush函數(shù),指示apache刷新輸出緩沖區(qū),但是內(nèi)容需要壓縮,apache就把內(nèi)容輸出到自身的mod_gzip模塊,mod_gzip也有自身的輸出 緩沖區(qū),他也不會馬上輸出,所以造成了內(nèi)容不能馬上輸出.為了改善這個情況,可以關(guān)閉mod_gzip模塊,或者在httpd.conf增加以下內(nèi)容,以禁止壓縮

SetEnv no-gzip dont-vary

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22328.html

相關(guān)文章

  • PHP基礎(chǔ)之輸出沖區(qū)基本概念、原理分析

    摘要:返回內(nèi)部緩沖區(qū)的內(nèi)容,關(guān)閉緩沖區(qū)。返回緩沖區(qū)的長度,如果緩沖區(qū)未被激活,則返回。得到所有輸出緩沖區(qū)的狀態(tài)。使用輸出緩沖,可以將讀取的文件讀入緩沖區(qū),達(dá)到一定大小時傳送給用戶,再繼續(xù)讀取,實現(xiàn)分片的效果。 一、概念 在PHP運(yùn)行的過程中,可以將會產(chǎn)生輸出的函數(shù)或操作結(jié)果暫時保存在PHP的緩沖區(qū),只有當(dāng)緩沖區(qū)滿了、或者PHP運(yùn)行完畢、或者在必要時候進(jìn)行輸出,才會將數(shù)據(jù)輸出到瀏覽器,此緩沖數(shù)...

    harryhappy 評論0 收藏0
  • 淺析PHP輸出緩沖控制

    摘要:默認(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運(yùn)行...

    wangjuntytl 評論0 收藏0
  • 【modernPHP專題(10)】理解output buffer

    摘要:磁盤高速緩存操作系統(tǒng)中使用磁盤高速緩存技術(shù)來提高磁盤的速度,對高速緩存復(fù)制的訪問要比原始數(shù)據(jù)訪問更為高效。因此,磁盤高速緩存在邏輯上屬于磁盤,物理上則是駐留在內(nèi)存中的盤塊。 1. 磁盤高速緩存(Disk Cache) 操作系統(tǒng)中使用磁盤高速緩存技術(shù)來提高磁盤的I/O速度,對高速緩存復(fù)制的訪問要比原始數(shù)據(jù)訪問更為高效。例如,正在運(yùn)行的進(jìn)程的指令既存儲在磁盤上,也存儲在物理內(nèi)存上,也被復(fù)...

    kelvinlee 評論0 收藏0
  • PHP下載文件方式

    摘要:下載文件的方式得到文件路徑從得到文件路徑務(wù)必使用上面這種方法得到路徑,不能簡單的字符串拼接得到路徑如果輸入的是就可以訪問任何路徑設(shè)置信息描述頁面返回的結(jié)果返回內(nèi)容的類型,此處只知道是二進(jìn)制流。 PHP下載文件的方式 1. 得到文件路徑 從$_GET[file]得到文件路徑 $path_parts = pathinfo($_GET[file]); $file_name = $path_...

    hikui 評論0 收藏0
  • PHP_Smarty

    摘要:體現(xiàn)了業(yè)務(wù)與顯示的分離,盡量分離。就負(fù)責(zé)判斷條件,并取出數(shù)據(jù)來。顯示的工作盡量靠前頁面緩存緩存,重要概念。減輕了數(shù)據(jù)庫的壓力。控制局部不緩存在標(biāo)簽中控制,該標(biāo)簽不緩存。模板調(diào)用特殊方法使用對象注冊的方式來解決。文件命名函數(shù)名定 模板 數(shù)據(jù)與表現(xiàn)層的標(biāo)簽分離 smarty是PHP 與 HTML代碼的分離 小型模板類 $smarty 的工作流程: 把需要顯示的全局變量,賦值塞到對象內(nèi)部的...

    printempw 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<