[php-src] Issue #7957: ob content cannot be clean from ob callback when exits/throws
| From: | KapitanOczywisty | Date: | Mon, 17 Jan 2022 13:21:35 +0000 |
| Subject: | [php-src] Issue #7957: ob content cannot be clean from ob callback when exits/throws | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-239068@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/7957
Comment Author: KapitanOczywisty
This is a bit hacky, but works. Callback in
ob_start have to return value to prevent
output, but we can exploit garbage collector to stop execution after handling callback return. As
far I know, there is no other way. Also, probably better would be to use Error and
set_exception_handler. https://3v4l.org/ZNr6L
```php
<?php
function debug($msg){
fwrite(STDOUT, sprintf("[Debug] %s\n", $msg));
}
// capture any unexpected output and exit execution
ob_start(function($buffer, $phase){
// prevent exit on ob_end_*()
if(($phase & PHP_OUTPUT_HANDLER_FINAL) === 0){
$f = new class ($buffer) {
public function __construct(private $buffer) {}
public function __destruct() {
debug('exit call');
exit();
// or
// throw new UnexpectedOutputException($this->buffer);
}
};
}
debug(sprintf("callback called, buffer: %s, type: %d", var_export($buffer, true),
$phase));
// prevent buffer call
return null;
}, 1);
// do some work on shutdown
register_shutdown_function(function() {
debug('ob_end_clean');
ob_end_clean();
debug('shutting down');
});
debug('echo x1');
echo 'x1';
debug('echo x2');
echo 'x2';
```