The situation is a little complex, but not hopeless, cause output will be buffered for different reasons, even at other stages, e.g. gzip, Apache, PHP (Fast)GCI vs. CLI (from commandline $ php -a
) - and there are different browsers, too!
That's also why PHP did rate it as "NOT a bug", so more something like "rtfm", which still may be worth an improvement -- meaning, you should (must?) have a look at all related parts of the manual, not only at that for one single function?! I know, this might feel exhausting, but if you don't understand the system, also small differences and also small changes during time will make you fail - and the lot of "does not work for me"-comments show that.
There are often general chapters in the PHP manual, e.g. Output Buffering, which also tries to explain the differences between System and User-Level Buffers! A MUST READ!
Although having some specific remarks on a lot of answers and comments above, I'm afraid, I'm still not allowed to comment...
So just a few basic reminders from my "research" (learning) results, if at least you dig into your setting and have read most of the PHP manual:
Always have a look at your current settings, by php.ini
and/or .htaccess
and other parts;
e.g. using <?php phpinfo(); ?>
// but do not leave access to that info on a public/productive system!!
For example my default with PHP 8.2.17 says ...
output_buffering = 4096
(spoiler: other versions of PHP may use integers instead of bools - always have a look at your version's manual - it's always good for a surprise)
- setting
output_buffering
to a value will turn user-level buffering ON like a ob_start()
- which I can not switch off at script-level via
var_dump( ini_set('output_buffering', 0) );
- results in false
indicating failure, can not be set
- buffering is good for performance or for changing ("rewrite") and for discarding already produced output (think of a header for shipping an image in case of an error, needing a different header)
- so to stop the buffering at a point in script, you may typically want a
ob_end_flush()
to send the current content, and end-ing buffering - not the 'clean' (discard buffer) version?
- output buffering can have also more levels (on the user "ob_..." side)
- the lowest (last frontier) is PHP's independent(!) system-level, controlled by
flush()
- and by the ob-vious misleading named
ob_implicit_flush()
(the default argument value is bool $enable = true
), which flushes (the System Buffer!) automatically on every bit of code block
- but we may still want a little buffering (for network and system performance?!) and would gain more output control with explicit use of
flush()
Well, you are right, I should show something more:
Disclaimer: Using (standard) 'text/html' without s.th. like <!DOCTYPE html>
will end up in "Quirks-Mode", what will provide another level of surprise - but do what you like ;)
<?php
header( 'Content-type: text/plain; charset=utf-8' );
//header( 'Content-type: text/html; charset=utf-8' );
//echo '<!DOCTYPE html>',PHP_EOL;
ob_end_flush(); // flush user buffer to deliver header data and end user-level buffering
ob_implicit_flush(true); // automatically flush system buffer on every code block
echo str_repeat(PHP_EOL, 5); // I like space
for( $i=10; $i>0; $i-- ){
echo $i,' ';
//flush(); // now done by _implicit_
sleep(1);
}
echo '*',PHP_EOL;
// final flushing always done by end of script
?>
Works for me :) well, even not obvious, so wish you good luck and endurance!
Live long and prosper \\//-
BRs Klaus