5

How does one stop calls to the ob_start callback when issue-ing *_clean() calls.

ob_start(function($buffer, $phase){
    // code here
}, 0, PHP_OUTPUT_HANDLER_FLUSHABLE | PHP_OUTPUT_HANDLER_REMOVABLE);

Doesn't prevent ob_end_clean, ob_get_clean or ob_clean calls from being ran. I'd expect a notice that the buffer wasn't started with the proper PHP_OUTPUT_HANDLER_CLEANABLE flag as per the docs.

As for the PHP_OUTPUT_HANDLER_* constants, I haven't found a suitable man page where the $phase parameter is explained and the groups of bits pertaining to those constants detailed. Even the actual names / values I've had to get them from the CONSTANTS global variable.

PHP_OUTPUT_HANDLER_START
PHP_OUTPUT_HANDLER_WRITE
PHP_OUTPUT_HANDLER_FLUSH
PHP_OUTPUT_HANDLER_CLEAN
PHP_OUTPUT_HANDLER_FINAL
PHP_OUTPUT_HANDLER_CONT
PHP_OUTPUT_HANDLER_END
PHP_OUTPUT_HANDLER_CLEANABLE
PHP_OUTPUT_HANDLER_FLUSHABLE
PHP_OUTPUT_HANDLER_REMOVABLE
PHP_OUTPUT_HANDLER_STDFLAGS
PHP_OUTPUT_HANDLER_STARTED
PHP_OUTPUT_HANDLER_DISABLED

Knowing these constants I've tried to limit so that no clean methods trigger my callback and short-circuit its logic. But I couldn't get the $phase content for any of the clean methods out (can't call printf, echo,ob_start from within the callback).

Maybe I'm going at this wrong, my scenario is:

  • I start a buffer at the beginning to process all output later
  • A lot of code that I don't control runs:

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

  • Triggers my callback even though it shouldn't as the code is not its owner / no cleanable flag was set

  • I trigger alerts for empty buffers even though it isn't the case as they reconstruct it in another buffer

Basically my questions are:

  • Am I able to stop such a thing?
  • If not is there another way?
Krotz
  • 615
  • 3
  • 9
  • 21

1 Answers1

0

If you have code which clears the whole buffer and you cannot control it - there's no way you get ob_* commands to work properly. You can implement your own buffer construction though and add output there manually.

The class might look like this

<?php

class MyBuffer
{
    static $buffer = '';

    public static function add(string $output)
    {
        self::$buffer .= $output;
    }

    public static function get()
    {
        return self::$buffer;
    }

    public static function get_clean()
    {
        $buffer = self::$buffer;
        self::$buffer = '';
        return $buffer;
    }
}

An you could use it in the following way

// ... some code
MyBuffer::add('Hello user, glad you joined us!');
// ... some more code
MyBuffer::add('Your socore is ' . $score . '. Congratz!');
// ...
echo MyBuffer::get_clean();
Bogdans
  • 145
  • 7