使用ob_start回调函数进行ob_get_clean

时间:2019-01-16 11:59:49

标签: php buffer

我正在尝试使用多个ob_start获得缓冲的输出。一些ob_start具有回调函数。函数调用但无效。

<?php
function callback($buffer)
{
    return "deleted\n";
}

ob_start();
echo "first\n";
ob_start("callback");
echo "second\n";
ob_start();
echo "third\n";

$final = '';
$levels = ob_get_level();

for ($i = 0; $i < $levels; $i++) {
    $final .= ob_get_clean();
}
echo $final;

预期结果是

third
deleted
first

但是我明白了

third
second
first

我做错了什么?

1 个答案:

答案 0 :(得分:0)

我也对此感到惊讶,文档对此可能会更加清晰。根据{{​​3}}:

ob_get_clean()本质上执行ob_get_contents()和 ob_end_clean()。

但是,$callback documentation中的ob_start($callback)

[...]输出缓冲区被刷新(发送)或清理(使用ob_flush(), ob_clean()或类似函数)或刷新输出缓冲区时 到请求末尾的浏览器。

调用$callback时已经调用ob_get_contents(),并且对$contents无效。

我们可以在is called when

中进行确认
PHP_FUNCTION(ob_get_clean)
{
    if (zend_parse_parameters_none() == FAILURE) {
        RETURN_THROWS();
    }

    if(!OG(active)) {
        RETURN_FALSE;
    }

    if (php_output_get_contents(return_value) == FAILURE) {
        php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer. No buffer to delete");
        RETURN_FALSE;
    }

    if (SUCCESS != php_output_discard()) {
        php_error_docref("ref.outcontrol", E_NOTICE, "Failed to delete buffer of %s (%d)", ZSTR_VAL(OG(active)->name), OG(active)->level);
    }
}

我认为这没有办法。您需要谨慎使用ob_get_contents()。如果要堆叠多个输出处理程序,请仅使用ob_start($callback)。如果可以选择在$callback和等效项上调用ob_get_contents(),那么肯定会很好。