我不确定这是一个错误还是一个特性。从PHP源代码来看,我发现在调用回调函数之前,ob_get_clean
的返回值已经被填充。
我看到至少有两种解决方案。第一种是手动对输出字符串进行回调处理。我认为这不需要举例说明。
第二种方法是利用堆栈输出缓冲区的可能性。由于成功刷新使用了回调函数,因此您可以将输出代码包装在额外的输出缓冲区中,并获取修改后的内容。
ob_start();
function callback($input) { return $input . " altered"; }
ob_start('callback');
echo "foo";
ob_end_flush();
$content = ob_get_clean();
ob_end_clean();
echo $content . "\n"; // prints "foo altered\n"
如果你感兴趣,可以查看
ob_get_clean
函数的源代码 (main/output.c)。你可以在 PHP 网站上获取源代码。以下是一些提示。
PHP_FUNCTION(ob_get_clean)
{
if (zend_parse_parameters_none() == FAILURE) {
return;
}
// THIS CALL FILLS THE RETURN VALUE
if (php_ob_get_buffer(return_value TSRMLS_CC) == FAILURE) {
RETURN_FALSE;
}
if (!OG(ob_nesting_level)) {
php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer. No buffer to delete");
zval_dtor(return_value);
RETURN_FALSE;
}
if (OG(ob_nesting_level) && !OG(active_ob_buffer).status && !OG(active_ob_buffer).erase) {
php_error_docref("ref.outcontrol" TSRMLS_CC, E_NOTICE, "failed to delete buffer %s", OG(active_ob_buffer).handler_name);
zval_dtor(return_value);
RETURN_FALSE;
}
// THIS CALL KILLS THE CURRENT BUFFER AND EXECUTES THE CALLBACK
php_end_ob_buffer(0, 0 TSRMLS_CC);
}
php_end_ob_buffer
函数获取 OB 缓冲区的内容并将回调函数应用于其中。如果第一个参数为 true,则将内容传递给下一个输出缓冲处理程序。在本例中,它为 false,因此即使执行了回调函数,但内容仍将丢失。