PHP何时准备发送响应头?header_register_callback中die()未拦截输出问题
问题原因说明
这是PHP 8.0.0 ~ 8.0.10版本的专属内核Bug,触发根源是该版本区间内header_register_callback的执行时序和输出缓冲区的处理逻辑存在冲突:
- 官方定义的回调触发时机是「所有响应头准备完成、任何其他输出发送之前」,此时执行
die/exit应当直接终止程序,不会处理后续业务代码的输出 - 但该版本区间的PHP内核实现存在漏洞:触发回调前,已经把后续业务代码生成的输出内容写入了底层输出缓冲区队列,回调中执行
die时没有清空已入队的缓冲区内容,直接将队列中已有的内容连同回调内的输出一起发送给了客户端,才会出现你遇到的异常输出
解决方案
有两种方式可以规避这个问题:
- 升级PHP到8.0.11及以上版本,该版本已经官方修复了这个Bug
- 暂时无法升级的话,在回调中执行
die/exit之前,手动清空所有输出缓冲区即可,修改后的回调代码参考如下:
function callback() { echo "In php 8.0.0 - 8.0.10, a die statement does prevent the trigger from being outputted: "; // 手动清空所有层级的输出缓冲区,避免已经入队的内容输出 while (ob_get_level() > 0) { ob_end_clean(); } die(); }
内容的提问来源于stack exchange,提问作者Rup7ur3
相关产品推荐
相关产品推荐

