# PHP緩沖區
>PHP中有一個"輸出緩沖區"層!首先要明確"輸出緩沖區"是基于PHP5.4(以及以上版本),PHP中的OB層從5.4版開始就發生了很多變化,確切說是完全重寫了,有些地方可能都不兼容PHP 5.3了。
## 什么是輸出緩沖區?
PHP的輸出流包含很多字節,通常都是程序員要PHP輸出的文本,這些文本大多是echo語句或者printf()函數輸出的。首先要明確,PHP的任何輸出都會用到緩沖區,但是如果是用PHP編輯擴展,用到的函數(C函數)可能會直接輸出寫到SAPI緩沖區,而不紅過OB層。
>[danger]"輸出緩沖區層"不是惟一用于緩沖區輸出的層,它實際上只是很多層中的一個。并且`輸出緩沖區層`與使用的(web和cli)有關。不同的SAPI可能有不同的行為。
>[info]CLI的SAPI有點特殊。CLI會將INI配置中的output_buffer選項強制設置為0,這表示禁用默認PHP輸出緩沖區。所以在CLI中,默認情況下你要輸出的東西會直接傳遞到SAPI層,除非你手動調用ob_()類函數。并且在CLI中,implicit_flush的值也會被設置為1。
## 默認PHP輸出緩沖區
如果你使用不同于CLI的SAPI,像PHP-FPM,你會用到下面三個跟緩沖區相關的INI配置選項:
- output_buffering
- implicit_flush
- output_handler
>[danger]不能在運行時使用ini_set()改這幾個選項的值。這些選項的值會在PHP程序啟動的時候,還沒有運行任何腳本之前解析,所以也許在運行時可以使用ini_set()改變它們的值,但改變后的值并不會生效,一切都已經太遲了,因為輸出緩沖區層已經啟動并已激活。你只能通過編輯php.ini文件或者是在執行PHP程序的時候使用-d選項才能改變它們的值。
>[info]默認情況下,PHP發行版會在php.ini中把output_buffering設置為4096個字節。如果你不使用任何php.ini文件(或者也不會在啟動PHP的時候使用-d選項),它的默認值將為0,這表示禁用輸出緩沖區。如果你將它的值設置為“ON”,那么默認的輸出緩沖區的大小將是16kb。你可能已經猜到了,在web應用環境中對輸出的內容使用緩沖區對性能有好處。默認的4k的設置是一個合適的值,這意味著你可以先寫入4096個ASCII字符,然后再跟下面的SAPI層通信。并且在web應用環境中,通過socket一個字節一個字節的傳輸消息的方式對性能并不好。更好的方式是把所有內容一次性傳輸給服務器,或者至少是一塊一塊地傳輸。層與層之間的數據交換的次數越少,性能越好。你應該總是保持輸出緩沖區處于可用狀態,PHP會負責在請求結束后把它們中的內容傳輸給終端用戶,你不用做任何事情。
>[danger]implicit_flush已在前面談論CLI的時候提到過。對于其他的SAPI,implicit_flush默認被設置為關閉(off),這是正確的設置,因為只要有新數據寫入就刷新SAPI的做法很可能并非你所希望的。對于FastCGI協議,刷新操作(flushing)是每次寫入后都發送一個FastCGI數組包(packet),如果發送數據包之前先把FastCGI的緩沖區寫滿會更好一些。如果你想手動刷新SAPI的緩沖區,使用PHP的flush()函數。如果你想寫一次就刷新一次,你可以設置INI配置中的implicit_flush選項,或者調用一次ob_implicit_flush()函數。
>[success]output_handler是一個回調函數,它可以在緩沖區刷新之前修改緩沖區中的內容。PHP的擴展提供了很>[success]多回調函數(用戶也可以自己編寫回調函數)。
- ob_gzhandler : 使用ext/zlib壓縮輸出
- mb_output_handler : 使用ext/mbstring轉換字符編碼
- ob_iconv_handler : 使用ext/iconv轉換字符編碼
- ob_tidyhandler : 使用ext/tidy整理輸出的HTML文本
- ob_[inflate/deflate]_handler : 使用ext/http壓縮輸出
- ob_etaghandler : 使用ext/http自動生成HTTP的Etag
>[success]緩沖區中的內容會傳遞給你選擇的回調函數(只能用一個)來執行內容轉換的工作,所以如果你想獲取PHP傳輸給web服務器以及用戶的內容,你可以使用輸出緩沖區回調。當前有一點也需要提一下,這里說的“輸出”指的是消息頭(headers)和消息體(body)。HTTP的消息頭也是OB層的一部分。
- 前言
- PHP獲取服務器信息
- PHP中的常用函數-新手必備知識
- 日期時間相關的函數
- 時區設置
- time函數
- strtotime 時間戳
- date函數
- mktime函數
- 聯合使用 date() 和 mktime()
- PHP數據類型相關的函數
- PHP數組相關的函數
- array函數
- 數組的排序
- sort()和rsort()函數
- asort()和arsort()函數
- ksort()和krsort()函數
- array_multisort()函數
- array_reverse函數
- 數組的遍歷
- 數組中新增和刪除元素
- 數組頭部插入和刪除元素
- 數組尾部插入和刪除元素
- 刪除數組中重復的元素
- 刪除數組中指定的元素
- 數組的合并
- 隨機/打亂已知數組
- range函數
- 數組去除重復
- PHP常用功能函數
- URL地址處理函數
- post/get請求
- PHP字符串相關的函數
- PHP文件系統
- PHP正則表達式
- 正則表達式語法規則
- POSIX擴展的正則表達式函數
- 查找字串函數
- 替換字符串函數
- Perl兼容的正則表達式函數
- PHP中類的應用
- 中文編碼
- 關于stdClass
- 變量相關函數
- unset
- PHP數值相關的函數
- 數值取整
- 開發工具與開發環境使用技巧
- sublime
- 常用插件
- Atom
- 常用插件
- 常見問題
- Visual Studio Code
- vscode常用插件
- 編程推薦字體
- MAC下開發常識
- MAC下的常用設置
- MAC下的常用開發工具
- MAC下XAMMP的常見問題
- Apache配置基礎
- PhpStrom
- php中的常見問題
- 文件上傳相關問題
- API接口中常見問題
- 關于緩沖區問題
- PHP中注意事項
- 條件判斷
- PHP文件管理模塊
- 文件管理源碼
- 文件管理的常用函數
- 文件管理中文亂碼處理
- 自定義功能函數
- 文件下載
- PHP常用頭信息定義匯總
- 常見PHP網頁木馬
- 加密算法
- 1. Base58可逆加密
- 2. AES加密/解密
- mysql數據庫操作
- 命令行操作Mysql常用令行-查詢
- 命令行操作Mysql常用令行-操作
- Mysql使用中的技巧
- 在線數據庫管理中常用命令
- sql show命令
- mysql數據庫的備份與恢復
- 二進制日志介紹
- 二進制日志常用命令
- ThinkPHP
- 數據遷移
- 常見問題
- 驗證碼問題
- API接口中的異常處理
- API接口安全
- 解決跨域問題
- 自定義實用功能函數