我有一个带回调函数的输出缓冲区。然而,当清理缓冲区时,回调函数会被执行,返回的字符串不会被更改。
我使用以下代码:
<?php
ob_start('callback');
print 'some text';
error_log(ob_get_clean());
function callback($content) {
error_log('callback');
return $content . ' altered';
}
输出:
callback
some text
我想要什么:
callback
some text altered
我错过了什么?我在CLI中使用PHP 5.3.10。
编辑:正在执行回调
来自PHP手册:
刷新(发送)输出缓冲区时将调用该函数或已清理(使用ob_flush()、ob_clean()或类似函数),或者输出缓冲区在请求结束时被刷新到浏览器。
我不确定这是一个bug还是一个功能。查看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 alteredn"
如果您感兴趣,请参阅ob_get_clean
(main/output.c)的源代码。您可以在PHP网站上获取源代码。以下是一些建议。
/* {{{ proto bool ob_get_clean(void)
Get current buffer contents and delete current output buffer */
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,因此即使执行了回调,内容也会丢失。
如果我有一个猜测,它会是这样的。
ob_get_clean()
返回缓冲区的结果,THEN清除缓冲区,触发修改内容的回调。
IE
从缓冲区中提取"some text",并准备根据"get"功能的要求返回。
接下来,将清理缓冲区,但在清理之前,将根据存在回调时各种ob函数的要求,对内容触发回调。
结果是缓冲区被返回(根据请求),但在之后被修改,因为get发生在clean之前。
刷新缓冲区时会调用它:
ob_start('callback');
print 'some text';
ob_end_flush();
function callback($content) {
return $content . ' altered';
}
第页。S它也适用于CLI。
PHP的CLI不使用输出缓冲(或者更具体地说,缓冲与ob_函数无关)。所以你的回拨被跳过了。
EDIT:事实上,我在确认CLI是否提供标准输出缓冲时遇到了问题。我会尝试ob_end_flush()
、ob_flush()
和flush()
。
我删除了ob_get_clean,您的代码就可以工作了。
ob_start('callback');
print 'some text';
//error_log(ob_get_clean());
$buffer = ob_get_flush();
function callback($content) {
return $content . ' altered';
}
我已经检查了输出,它收到了一些文本警报。
为什么使用obgetclean()方法?它会清理缓冲区。
<?php ob_start('callback'); ?>
Foo Bar Baz
<?php
ob_end_flush();
function callback($content) {
$find = "Baz";
$replace_with = "Foo";
return (
str_replace($find, $replace_with, $content)
);
}
?>