PHP中的輸出緩沖控制在 PHP 中,我們直接進(jìn)行 echo 、 或者 print_r 的時(shí)候,輸出的內(nèi)容就會(huì)直接打印出來。但是,在某些情況下,我們并不想直接打印,這個(gè)時(shí)候就可以使用輸出緩沖控制來進(jìn)行輸出打印的控制。當(dāng)然,這一套功能并不僅限出針對(duì)打印的內(nèi)容,我們還可以做其它一些操作,這個(gè)我們放到最后再說。 清除輸出首先,我們先來看看不讓 echo 之類的內(nèi)容打印輸出。 ob_start();相信有不少小伙伴應(yīng)該見過 ob_start() 這個(gè)函數(shù),它的作用就是開始一段輸出緩沖控制。在 ob_start() 之后的代碼中的輸出語(yǔ)句都會(huì)進(jìn)入輸出緩沖區(qū),這個(gè)時(shí)候,如果我們調(diào)用了 ob_end_clean() 、 ob_clean() 或者 ob_get_clean() ,則不會(huì)有任何輸出了。它們?nèi)齻€(gè)的作用都是清除輸出緩沖區(qū)的內(nèi)容。具體的區(qū)別大家可以參考文章最后給出的函數(shù)說明或者官方文檔。 獲得輸出緩沖區(qū)的內(nèi)容ob_start();上面說過,使用了 ob_end_clean() 就會(huì)清除輸出緩沖區(qū)里面的內(nèi)容,但是在這段代碼中,我們使用 ob_get_contents() 函數(shù)直接將緩沖區(qū)的內(nèi)容賦值給了變量 \$v 。這時(shí)候,$v 中就有了前面兩段 echo 中的內(nèi)容,也就是說,這個(gè)一套操作我們就拿到了本身應(yīng)該輸出的內(nèi)容,并將它保存在了變量中。這樣做有什么用呢?我們可以獲得類似于 phpinfo() 、 var_dump() 這些直接輸出函數(shù)的內(nèi)容了,并且不會(huì)打印在客戶端屏幕上。比如: ob_start();在 $v 中的內(nèi)容就是 php_info() 的內(nèi)容了。這就是輸出緩沖控制的第二個(gè)能力。 刷新(輸出)緩沖區(qū)內(nèi)容ob_start();類似的,我們?cè)诰彌_區(qū)中想要再次直接輸出內(nèi)容,使用 flush() 、ob_flush() 、 ob_end_flush() 及 ob_get_flush() 就可以了,其實(shí)就是相當(dāng)于讓 ob_start() 之后的 echo 這類輸出語(yǔ)句重新生效并正常輸出。 另外,我們還可以使用一個(gè)函數(shù)進(jìn)行自動(dòng)的刷新。 ob_implicit_flush();使用 ob_implicit_flush() 之后,我們就不需要手動(dòng)地調(diào)用 ob_flush() 之類的函數(shù)來刷新緩沖區(qū)內(nèi)容了。 一些檢測(cè)函數(shù)ob_start();ob_get_length() 會(huì)返回當(dāng)前緩沖區(qū)里面內(nèi)容的長(zhǎng)度,這里我們只打印了一個(gè) 123 ,在緩沖區(qū)中保存了3個(gè)字符,所以輸出的正是 3 。ob_get_level() 返回的是當(dāng)前緩沖區(qū)的層級(jí),請(qǐng)注意,我們?cè)谏厦嬲{(diào)用了兩次 ob_start() ,也就是有兩層的緩沖區(qū),這個(gè)緩沖區(qū)是可以嵌套的。ob_get_status() 函數(shù)是緩沖區(qū)的狀態(tài)信息,字段的說明可以查看官方文檔,這里不再贅述。 使用 ob_start() 的回調(diào)函數(shù)來進(jìn)行輸出緩沖區(qū)的內(nèi)容替換這是一個(gè)例子,但是可以推廣到其他很功能,比如我們可以用來進(jìn)行全局的輸出過濾、可以做 CSS 或 JS 文件的壓縮優(yōu)化等等。 ob_start(function($text){最后的輸出結(jié)果就是將 apples 內(nèi)容替換成了 oranges 內(nèi)容。 添加 URL 重寫器output_add_rewrite_var('var', 'value');上面的代碼看出什么端倪了嘛?沒錯(cuò),使用 output_add_rewrite_var() 函數(shù),我們可以在 PHP 輸出的時(shí)候?yàn)?HTML 的鏈接或者表單代碼增加一個(gè)參數(shù)。有沒有想到什么使用場(chǎng)景?POST 表單的 CSRF 攻擊的防范。 這個(gè)函數(shù)會(huì)根據(jù) php.ini 文件中的 url_rewriter.tags 配置項(xiàng)來進(jìn)行添加,在默認(rèn)情況下這個(gè)配置項(xiàng)只支持 from 表單,同時(shí),它還可以支持 a 標(biāo)簽的href 、 area標(biāo)簽的href 、 frame標(biāo)簽的src 、 input標(biāo)簽的src 等等。也就是說,會(huì)在這些標(biāo)簽相對(duì)應(yīng)的屬性中自動(dòng)添加字段。當(dāng)然,它也有一個(gè)反函數(shù) output_reset_rewrite_vars() 用于取消之前增加的這個(gè)參數(shù)。 總結(jié)關(guān)于輸出緩沖控制這塊還有很多好玩的東西,不過限于篇幅我們先介紹到這里,將來踫到什么好的功能的應(yīng)用我們?cè)賳为?dú)講解?,F(xiàn)在基于 Swoole 的應(yīng)用越來越多,當(dāng)我們需要將 TP 、 Laravel 這類傳統(tǒng)框架轉(zhuǎn)換成支持 Swoole 的時(shí)候,往往就需要在入口文件使用輸出緩沖控制來進(jìn)行修改。因?yàn)閭鹘y(tǒng)框架基本都是直接進(jìn)行 echo 之類的輸出的,而在 Swoole 中,echo 這類的內(nèi)容是直接打印在控制臺(tái)的,這就需要我們通過 ob_get_contents() 能力獲得全部的輸出再通過 response->end() 來進(jìn)行實(shí)際的響應(yīng)。另外,還有一些其他的場(chǎng)景也會(huì)用到輸出緩沖控制:
最后,再給出輸出緩沖控制相關(guān)的函數(shù)說明,具體內(nèi)容大家還是要多看官方文檔的介紹。
測(cè)試代碼: https://github.com/zhangyue0503/dev-blog/blob/master/php/202005/source/%E8%BF%98%E6%90%9E%E4%B8%8D%E6%87%82PHP%E4%B8%AD%E7%9A%84%E8%BE%93%E5%87%BA%E7%BC%93%E5%86%B2%E6%8E%A7%E5%88%B6%EF%BC%9F.php 參考文檔: https://www./manual/zh/ref.outcontrol.php https://www./manual/zh/session.configuration.php#ini.url-rewriter.tags https://blog.csdn.net/xiaofan1988/article/details/43124359 |
|
|