PHP 8.3.4 Released!

flush

(PHP 4, PHP 5, PHP 7, PHP 8)

flushVaciar el búfer de salida del sistema

Descripción

flush(): void

Vacía los búferes de escritura del sistema de PHP y de cualquiera que sea el backend en el que se esté usando PHP (CGI, un servidor web, etc.). Trata de enviar toda la salida producida hasta el momento al navegador, aunque se ha de tener en cuenta algunas cosas.

flush() podría no sobreescribir el esquema del almacenamiento en búfer del servidor web, por lo que no tiene efecto sobre ningún búfer en el lado del cliente del navegador. Tampoco afecta al mecanismo del búfer de salida del espacio de usuario de PHP. Esto significa que se ha de llamar tanto a ob_flush() como a flush() para volcar los búferes de salida si se están usando aquellos.

Algunos servidores, especialmente en Win32, seguirán almacenando en búfer la salida producida por un script hasta que éste termine antes de transmitir los resultados al navegador.

Puede que algunos módulos de servidor para Apache, como mod_gzip, usen búferes propios que causarán que flush() no resulte en un envío inmediato de los datos al cliente.

Incluso el navegador puede almacenar en búfer su entrada antes de mostrarla. Netscape, por ejemplo, almacena en búfer el texto hasta que recibe un final de línea o el comienzo de una etiqueta, por lo que no interpretará las tablas hasta que se encuentre la etiqueta </table> de la tabla más externa.

Algunas versiones de Microsoft Internet Explorer solo empezarán a mostrar la página después de que han recibido 256 bytes de salida, por lo que puede que sea necesario enviar espacios en blanco extra antes del volcado para que se muestre la página en tales navegadores.

Valores devueltos

No devuelve ningún valor.

Ver también

  • ob_flush() - Vaciar (enviar) el búfer de salida
  • ob_clean() - Limpiar (eliminar) el búfer de salida
  • ob_end_flush() - Volcar (enviar) el búfer de salida y deshabilitar el almacenamiento en el mismo
  • ob_end_clean() - Limpiar (eliminar) el búfer de salida y deshabilitar el almacenamiento en el mismo

add a note

User Contributed Notes 24 notes

up
54
js at jeansebastien dot com
18 years ago
This will show each line at a time with a pause of 2 seconds.
(Tested under IEx and Firefox)

<?php

if (ob_get_level() == 0) ob_start();

for (
$i = 0; $i<10; $i++){

echo
"<br> Line to show.";
echo
str_pad('',4096)."\n";

ob_flush();
flush();
sleep(2);
}

echo
"Done.";

ob_end_flush();

?>
up
21
Ghostshaw at spymac dot com
18 years ago
I would like to point out that there is a function to replace ob_flush and flush. If you set ob_implicit_flush(true); at the top of the page it will automatically flush any echo or print you do in the rest of the script.

Note that you still need a minimum amount of data to come through the browser filter. I would advice using str_pad($text,4096); since this automatically lenghtens the text with spaces to 4 KB which is the minimum limit when using FireFox and linux.

I hope this helps you all out a bit.
up
8
fran at fran dot cr
3 years ago
If you want to make flush work when using php-fpm from Apache httpd with mod_proxy_fcgi, since 2.4.31 you can append flushpackets=on to enable flushing, which is instant by default, and and flushwait=n where n is in milliseconds to delay the flushing time for performance seconds.

These values can be appended to the <Proxy> directive, e.g. <Proxy "fcgi://localhost/" flushpackets=on flushwait=500> or in ProxyPass and ProxyPassMatch lines.

The mod_proxy_fcgi documentation for 2.4 does not document this, but it is available in the 2.5 or trunk documentation.
up
21
mandor at mandor dot net
15 years ago
This is what I use to turn off pretty much anything that could cause unwanted output buffering and turn on implicit flush:

<?php

@apache_setenv('no-gzip', 1);
@
ini_set('zlib.output_compression', 0);
@
ini_set('implicit_flush', 1);
for (
$i = 0; $i < ob_get_level(); $i++) { ob_end_flush(); }
ob_implicit_flush(1);

?>

If it still fails though, keep in mind that Internet Explorer and Safari have a 1k buffer before incremental rendering kicks in, so you'll want to output some padding as well.
up
3
Anonymous
4 years ago
Regarding buffering by browser you can use:

$out=str_pad($yourMessage.'<br/>',1024);
print($out);
ob_flush();
flush();

Works for me in Firefox 60 ESR.
up
16
php at stelio dot net
10 years ago
For a Windows system using IIS, the ResponseBufferLimit takes precedence over PHP's output_buffering settings. So you must also set the ResponseBufferLimit to be something lower than its default value.

For IIS versions older than 7, the setting can be found in the %windir%\System32\inetsrv\fcgiext.ini file (the FastCGI config file). You can set the appropriate line to:
ResponseBufferLimit=0

For IIS 7+, the settings are stored in %windir%\System32\inetsrv\config. Edit the applicationHost.config file and search for PHP_via_FastCGI (assuming that you have installed PHP as a FastCGI module, as per the installation instructions, with the name PHP_via_FastCGI). Within the add tag, place the following setting at the end:
responseBufferLimit="0"
So the entire line will look something like:
<add name="PHP_via_FastCGI" path="*.php" verb="*" modules="FastCgiModule" scriptProcessor="C:\PHP\php-cgi.exe" resourceType="Either" responseBufferLimit="0" />
Alternatively you can insert the setting using the following command:
%windir%\system32\inetsrv\appcmd.exe set config /section:handlers "/[name='PHP_via_FastCGI'].ResponseBufferLimit:0"
up
13
no at spam dot com
17 years ago
ob_flush();flush();

Not the other way around, because it wont work.
up
5
glafarge
3 years ago
When using PHP with mode CGI/FastCGI there is a new buffer (initiated by mod_fcgid with a default size of 65536 bytes). That causes `flush()` and `ob_flush()` not working as expected with implicit_flush(true).
Setting "OutputBufferSize 0" in mod_fcgid config resolves the issue.
Hope it helps !
up
4
mikael at oebb dot net
18 years ago
Hi all.
Been scratching my head over data NOT flushed to IE (6) even though I tried strpad 4096 chars, all headers OK, TABLE and no TABLE, flush and ob_flush - still a blank page. Tried adding a sleep(1) before flushing - and everything worked as a charm.

/Mikael
up
5
siggi AT june systems DOT com
19 years ago
After searching through the PHP site, google and various forums, not finding a solution to my script not outputting anything while calling flush and ob_flush, I thought of trying to tell PHP to call:

session_write_close();

before starting echo'ing. It worked like a charm. I couldn't find any references to this, so I hope this note will help someone in the future.
up
6
David
15 years ago
mod_security 2.x core rules will also prevent flush() from working.
up
5
Marty
18 years ago
This is an extention of Rusty's comment below:

After sitting here for hours trying to make IE6 flush data out in the middle of a page (with it working perfectly in Firefox), I finally figured out the problem. IE will not display flushed data (even if it has it) unless the table that contains it is complete.

Every new element you want IE to display must not be in ANY kind of table at all. You must end all your tables.
up
6
MOELZE �T GMX DOt DE (Michael)
18 years ago
It is a bit complicated to work with the funktion flush() and you have to experiment with it a bit.
So if you design a site which has a timeloop at the end that calls a other site via a form data input (Data Submit) you have
to give something out to the buffer to get that new site loaden quick.

For example:

<?php
$instant
=gettimeofday();
$timenow=$instant["sec"];//Start Time

//timeloop(e.g. for security_save after 30 min)
while (1) { echo "<b></b>";//Useless (only to quickload next
//or same Site when do a switch)
flush(); //giveout buffer
$instant=gettimeofday();
$timeactual=$instant["sec"]; //get Actual Time in Secs
$flag=(($timeactual>$timenow+$diff)? 1:0);//$diff=switchTime
if ($flag) { what_do_at_switch_Time();//Sec.Save etc.etc.
$timenow=$timeactual; } //Set new Start Time
sleep(5); //Or so...(Important)
} //End of while-Loop
?>

So you can programm a security save or other function in your site and if you do a switch the upload of the new or same site (the called site) works...
up
5
seb dot field at gmail dot com
13 years ago
If flush() function does not work. You must set next options in php.ini like:

--[code]--
output_buffering = Off
;output_handler =
zlib.output_compression = Off
;zlib.output_handler =
--[^code^]--

If things does not work you must view headers from the server and check `Server` string.
In my case, as the frontend was Nginx webserver and Apache work as backend.
Accordingly, buffering must be disabled in Nginx config file.
To stop buffering you must add next string to config file:

--[code]--
proxy_buffering off;
--[^code^]--

and restart Nginx daemon. More information about configuration you find in documentation on the nginx website.
up
3
php nospace juju ta ggooggle mail
8 years ago
combining some ideas i was finally able to get a long running script to give me real time feedback on what it was doing. this was a wamp setup with php running as cgi. i'm pretty sure that apache just wasn't sending any of the buffered output because it was trying to be helpful. also trying to be helpful, i hope this example solution helps someone.

<?php
// thx mandor at mandor
ini_set('max_execution_time', 0);
ini_set('implicit_flush', 1);
ob_implicit_flush(1);

echo
'doing something'; my_flush();
sleep(5);
echo
'doing something else'; my_flush();
sleep(5);
echo
'finally done - hooray';

function
my_flush() {
// following matt at hevanet's lead
for ($i=0;$i<10000;$i++) echo ' ';
ob_flush();
flush();
}
up
4
Kris
11 years ago
I had a bunch of problems trying to get flush working on my windows box, I finally found a solution after reading everyones here and it not working.

1) Set output_buffering = 0
2) Set zlib.output_compression = 0

I then used Wireshark to monitor network packets, and indeed the server was pusing the data, but the browser was not displaying it.. So it was a browser buffer issue (I am on Firefox 13)

For me I needed to send about 1k of data before it would display the data. To do this I added more header information..
In php.ini I set default_charset = "utf-8"
And that was enough to give me enough for the buffer issue.

You can also try doing
echo str_repeat(" ", 1024), "\n";
at the start of the script.

hope this helps
up
4
matt at nospamplease dot hevanet dot com
18 years ago
Like IE, Safari needs a fair amount of data before it'll display anything, actually more than explorer. The following code works for me in Firefox and Safari, and should work in IE as well.

<?php

for($i = 0; $i < 40000; $i++)
{
echo
' '; // extra spaces
}
// keeps it flowing to the browser?
flush();
// 50000 microseconds keeps things flowing in safari, IE, firefox, etc
usleep(50000);

?>

This code came from a comment on a blog discussing browser functionality with flush();
up
2
Leon
16 years ago
I've spent days trying to figure out why flush didn't work all of a sudden, while it used to work perfectly. Apparently, it was McAfee Spamkiller that caused problems. Disabling it didn't work, I had to completely remove it. Hope this helps someone.
up
2
Kirk
17 years ago
If you're not explictly using the buffering functions, then ob_flush() is only necessary if output buffering is turned on in your php.ini file.

flush() is only necessary if implicit_flush is turned off in your php.ini file. Setting implicit_flush to on will remove the need for all these flush() calls, but it's generally only good in an extremely controlled environment. Turning on implicit_flush in a production environment can be bad.
up
1
Arerano
15 years ago
This helped me getting flushing to work.
Using apache with deflate.

Turning compression off for this script: (add it somewhere at the top of the script)
apache_setenv('no-gzip', '1');

However, this only works if php is running as a module rather than a cgi-extension and safe mode must be disabled.

You can also turn the compression off for a directory by making a .htaccess file and adding the following entry:
mod_gzip_on Off

However that affects the whole directory.
Hope I could help.
up
0
remco dot pc at outlook dot com
1 month ago
on php8.3-fpm with apache 2.4.57

In order flush to work in the browser you need to send some more data (at least 4096 bytes / flush) and you need to add a setting for that site to the virtual host of your apache2 configuration:

<FilesMatch \.php$>
SetHandler "proxy:unix:/run/php/php8.3-fpm.sock|fcgi://localhost"
</FilesMatch>
<Proxy fcgi://localhost/">
ProxySet enablereuse=on flushpackets=on
</Proxy>
up
0
mbilliet at gmail dot com
16 years ago
Hello,

I had the same problems with sending a javascript after the <body></body> content has been sent to the browser (the script updates the content of an iframe).

Two solutions work for me:
- add enough data (i.e.: extra dummy text like spaces) or,
- echo the '</body>' tag at the end of the page

Note, that for the latter to work one should:
- turn of output_buffering in php.ini and either:
* turn on implicit_flush in its php.ini or,
* call ob_implicit_flush(); at the beginning of a script

I preferr echoing the '</body>' tag at the end as it doesn't require any extra data to be sent over the wire and its much a neater coding technique.

Notes:
- these worakarounds aren't needed when using perl and cgi,... .
- you can leave the zlib.output_compression in your php.ini switched on

Kind regards and hoped this is of any help.

Maurits
up
0
crmacd at yahoo dot com
19 years ago
I figured out a way to create a simple progress bar that is for the most part cross platform. Seeing as I got my ideas from this site it's only share to give back to the community.

Note: Something interesting about browser buffering... you have to have the <html><body> for Firefox and some other browsers to recognize items by their id in Javascript. So I recommend using some sort of header function before calling this function.

<?php

function fn_progress_bar($intCurrentCount = 100, $intTotalCount = 100)
{
static
$intNumberRuns = 0;
static
$intDisplayedCurrentPercent = 0;
$strProgressBar = '';
$dblPercentIncrease = (100 / $intTotalCount);
$intCurrentPercent = intval($intCurrentCount * $dblPercentIncrease);
$intNumberRuns++;

if(
1 == $intNumberRuns)
{
$strProgressBar = <<< BAR
<table width='50%' id='progress_bar' summary='progress_bar' align='center'><tbody><tr>
<td id='progress_bar_complete' width='0%' align='center' style='background:#CCFFCC;'>&nbsp;</td>
<td style='background:#FFCCCC;'>&nbsp;</td>
</tr></tbody></table>
<script type='text/javascript' language='javascript'>
function dhd_fn_progress_bar_update(intCurrentPercent)
{
document.getElementById('progress_bar_complete').style.width = intCurrentPercent+'%';
document.getElementById('progress_bar_complete').innerHTML = intCurrentPercent+'%';
}
</script>
BAR;
}
else if(
$intDisplayedCurrentPercent <> $intCurrentPercent)
{
$intDisplayedCurrentPercent = $intCurrentPercent;
$strProgressBar = <<< BAR
<script type='text/javascript' language='javascript'>
dhd_fn_progress_bar_update(
$intCurrentPercent);
</script>
BAR;
}
if(
100 <= $intCurrentPercent)
{
$intNumberRuns = $intDisplayedCurrentPercent = 0;
$strProgressBar = <<< BAR
<script type='text/javascript' language='javascript'>
document.getElementById('progress_bar').style.visibility='hidden';
</script>
BAR;
}
echo
$strProgressBar;
flush();
ob_flush();
}

?>
up
0
scottmacvicar at ntlworld dot com
20 years ago
Regarding Apache2
flush() will produce the same results as ob_flush() when output buffering is involved.
To Top