简体   繁体   中英

ob_get_clean with ob_start callback function

I'm trying to get buffered output with a multiple ob_start. Some ob_start has callback functions. Functions calls but with no effect.

<?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;

Expected result is

third
deleted
first

But I get

third
second
first

What I'm doing wrong?

I was surprised by it as well, and the documentation could be more clear about this. According to the documentation :

ob_get_clean() essentially executes both ob_get_contents() and ob_end_clean().

However, the $callback of ob_start($callback) is called when :

[...] the output buffer is flushed (sent) or cleaned (with ob_flush(), ob_clean() or similar function) or when the output buffer is flushed to the browser at the end of the request.

When $callback is called ob_get_contents() has already been called and it has no effect on $contents .

We can confirm it in PHP source code:

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);
    }
}

I don't think there's a way around this. You need to be careful with how you use ob_get_contents() . If you want to stack multiple output handlers use only ob_start($callback) s. It sure would be nice, if there was an option to invoke the $callback on ob_get_contents() and equivalents.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM