ob_start()后未调用ob_end_flush()或ob_end_clean()会导致输出丢失;嵌套缓冲需逐层关闭;误用ob_get_contents()不清理会内存溢出;output_buffering=4096会掩盖headers已发送错误。

ob_start() 后不调用 ob_end_flush() 会丢数据
PHP 输出缓冲区默认关闭,ob_start() 开启后,所有 echo、print、HTML 输出都会暂存在内存里,不会立即发给浏览器。如果忘记配对调用 ob_end_flush() 或 ob_end_clean(),脚本结束时 PHP 会自动清空缓冲区——但此时输出已丢失,页面可能空白或只显示部分 HTML。
常见场景:封装模板渲染函数、捕获第三方库的输出、动态生成 CSS/JS 内联内容。
- 必须在
ob_start()后显式调用ob_end_flush()(送出并关闭)或ob_end_clean()(丢弃并关闭) - 嵌套调用
ob_start()时,每层都需对应一次ob_end_*(),否则外层缓冲区可能截断内层内容 - 使用
register_shutdown_function()补救不可靠——缓冲区已在脚本终止前被销毁,无法保证执行时机
ob_get_contents() 和 ob_get_clean() 的行为差异很关键
ob_get_contents() 只读取当前缓冲区内容,不改变缓冲区状态;ob_get_clean() 则读取后自动 ob_end_clean()。误用会导致后续输出错乱或重复捕获。
典型错误:在循环中反复 ob_start() + ob_get_contents() 却没清理,结果缓冲区越积越多,内存暴涨甚至超限报错 Fatal error: Allowed memory size exhausted。
立即学习“PHP免费学习笔记(深入)”;
- 需要多次捕获不同片段时,优先用
ob_get_clean(),避免残留 - 若要保留缓冲区继续写入(比如拼接多个区块),用
ob_get_contents()+ 手动ob_flush()控制发送节奏 -
ob_get_length()比strlen(ob_get_contents())更安全,它返回实际缓冲字节数,不受字符编码影响
开启 output_buffering = 4096 会影响 header() 调用时机
php.ini 中设置 output_buffering = 4096(或 On)会让 PHP 自动启用默认缓冲区。这看似省事,但会掩盖 header() 报错:Warning: Cannot modify header information - headers already sent。
原因:哪怕只是开头多了一个空格或 UTF-8 BOM,PHP 也会在首次输出时隐式调用 ob_start(),导致 headers 实际已发送。开发环境建议设为 0,强制暴露输出污染问题。
- 线上环境可开,但必须确保所有文件无 BOM、无多余空白、
header()前无任何输出(包括require进来的文件) -
headers_sent()是唯一可靠检测方式,不要依赖 try/catch —— 它抛的是 warning,不是 exception - CLI 模式下
output_buffering默认关闭,ob_start()仍有效,但ob_flush()对终端无效,仅影响ob_get_*()系列函数
gzip 压缩和 ob_gzhandler 不能和 zlib.output_compression 共存
同时启用 zlib.output_compression = On 和手动注册 ob_start('ob_gzhandler') 会导致双重压缩,浏览器解压失败,表现为页面乱码或白屏。PHP 7.4+ 已废弃 ob_gzhandler,更推荐用内置配置。
真实调试场景:Nginx 后面跑 PHP-FPM,发现响应头有 Content-Encoding: gzip 但内容不可读,大概率是压缩层叠加了。
- 选一种压缩方式即可:
zlib.output_compression = On(全局) 或ob_start('gzencode')(按需) - 用
ob_start(['gzencode', 6])可指定压缩等级,但注意gzencode返回的是原始压缩流,需确保客户端支持且未被中间件截断 - 检查是否生效:打印
ini_get('zlib.output_compression')和ob_list_handlers(),后者能列出当前激活的回调函数
缓冲区嵌套层数、自动清理时机、与 SAPI(如 Apache/Nginx/CLI)的交互细节,这些地方没有文档会明说,但每次部署环境切换都可能触发异常输出行为。



















