PHP ob_get_status()的flags项存在未文档化位且输出缓冲未调用
PHP 5.4+ 输出缓冲未文档化flags含义与透传问题根因
未公开flags位定义
你观测到的flags值12401转换为二进制为0b11000001110001,其中两位未文档化的高位标记均为PHP 5.4输出缓冲重构后新增的内部状态位,含义如下:
- 第13位(对应数值4096 = 2^12):内部常量
PHP_OUTPUT_HANDLER_DISABLED,表示当前输出处理程序已被禁用,不再处理任何写入的内容 - 第14位(对应数值8192 = 2^13):内部常量
PHP_OUTPUT_HANDLER_PASSTHRU,表示当前缓冲开启透传模式,所有写入内容会直接转发到上一层缓冲,不会在当前层存储或经过回调处理
缓冲透传问题解释
上述两个标记完全可以解释你遇到的内层缓冲为空的现象:当PHP_OUTPUT_HANDLER_PASSTHRU被置位时,所有写入RequestLogger缓冲的内容都会直接透传到外层FatalErrorHandler缓冲,所以当前层的buffer_used始终为0,不需要你显式调用flush操作。
PHP 5.4重构输出缓冲后新增了自动触发这两个标记的逻辑,满足以下任意条件就会自动置位:
- 你传入
ob_start的RequestLogger回调函数返回了false,或者返回的字符串长度小于输入的内容长度 RequestLogger回调函数执行过程中抛出了未被捕获的异常
PHP 5.3中没有这套自动禁用+透传的逻辑,回调返回异常值时只会忽略返回结果,继续正常缓冲内容,所以不会出现该问题,和你观测到的版本差异完全匹配。
修复方案
- 检查
RequestLogger回调的返回逻辑:如果不需要修改输出内容,必须直接返回输入的原始字符串,不要返回空值、false或者截断后的字符串 - 给回调函数添加异常捕获逻辑,所有内部异常必须在回调内处理完成,不要抛出到外层
- 可以在调用
ob_start时显式指定flags参数为PHP_OUTPUT_HANDLER_STDFLAGS,强制使用公开标准标记,避免内部隐式标记的影响
内容的提问来源于stack exchange,提问作者HappyDog
相关产品推荐
相关产品推荐

