Let's look at a piece of code first:
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
flush();
sleep(1);
}
?〉
According to the php manual, this function sends all outputs of the program to the user's browser so far.
The above code should output $i once every second. But in reality, this is not necessarily the case. It is possible that after waiting for 10 seconds, all the outputs are presented at the same time.
OK, let's change this code and change it to
〈?php
ob_end_clean();//Modify part
for ($i=10; $i〉0; $i--)
{
echo $i;
flush();
sleep(1);
}
?〉
Hey, add this sentence ob_end_clean();, it's OK. In fact, it is also OK to replace ob_end_clean() with ob_end_flush().
I'll change it again.
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();//Modify part
flush();
sleep(1);
}
?〉
After running it, do you find that $i is output once every second? Why is this?
Don't worry, let's take a look.
Open, search for output_buffering, and we will see settings like this, output_buffering = 4096. Just like its name output_buffering, the purpose of this setting is to buffer the output, with a buffer size of 4096bytes.
In our first piece of code, the reason why the output_buffering did not output as expected is because this output_buffering buffered all the outputs. If 4096bytes is not reached or the script is finished, the output will not be sent out.
The function of ob_end_clean() and ob_end_flush() in the second code is to terminate the buffering. In this way, you don't have to wait until there is a buffer of 4096bytes before it is sent out.
In the third paragraph of code, ob_flush() is used. Its function is to send the buffered data, but it will not terminate the buffering, so it must be used before each flush().
If we do not want to use ob_end_clean(), ob_end_flush() and ob_flush(), we must set the output_buffering in it to be small enough, for example, set to 0. It should be noted that if you plan to use ini_set("output_buffering","0") in your script to set it, then please stop, this method does not work. Because at the beginning of the script, the buffering settings are already loaded, and the buffering begins.
Maybe you will ask, since ob_flush() sends the buffered data, why do you still need to use flush()??? Isn't it possible to directly use the following code? ?
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();
sleep(1);
}
?〉
Please note the difference between ob_flush() and flush(). The former releases data from the PHP buffer, while the latter sends data that is not in the buffer or is released to the browser. So when the buffer exists, we must use ob_flush() and flush() at the same time.
Is flush() indispensable here? No, we have another method, so that when there is data output, it will be sent to the browser immediately. The following two pieces of code do not require flush(). (When you set output_buffering to 0, you don’t even need ob_flush() and ob_end_clean())
〈?php
ob_implicit_flush(true);
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();
sleep(1);
}
?〉
〈?php
ob_end_clean();
ob_implicit_flush(true);
for ($i=10; $i〉0; $i--)
{
echo $i;
sleep(1);
}
?〉
Please pay attention to the above ob_implicit_flush(true). This function forces the output to immediately send to the browser whenever there is output. This way, there is no need to use flush() to send it to the browser after each output (echo).
The above complaints may not be valid in some browsers. Because browsers also have their own rules. I used Firefox1.5, IE6, opera8.5 to test it. Opera cannot output normally because it has a rule, that is, if you don’t encounter an HTML tag, you will definitely not output unless the script ends. FireFox and IE are quite normal.
Finally, a very interesting code is attached, the author is PuTTYshell. In a script cycle, each output will be overwritten by the previous output.
The following code is only available under firefox, and other browsers do not support the Content-Type of multipart/x-mixed-replace.
〈?php
header('Content-type: multipart/x-mixed-replace;boundary=endofsection');
print “\n--endofsection\n“;
$pmt = array(“-“, “\\“, “|“, “/“ );
for( $i = 0; $i 〈10; $i ++ ){
sleep(1);
print “Content-type: text/plain\n\n“;
print “Part $i\t“.$pmt[$i % 4];
print “--endofsection\n“;
ob_flush();
flush();
}
print “Content-type: text/plain\n\n“;
print “The end\n“;
print “--endofsection--\n“;
?〉
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
flush();
sleep(1);
}
?〉
According to the php manual, this function sends all outputs of the program to the user's browser so far.
The above code should output $i once every second. But in reality, this is not necessarily the case. It is possible that after waiting for 10 seconds, all the outputs are presented at the same time.
OK, let's change this code and change it to
〈?php
ob_end_clean();//Modify part
for ($i=10; $i〉0; $i--)
{
echo $i;
flush();
sleep(1);
}
?〉
Hey, add this sentence ob_end_clean();, it's OK. In fact, it is also OK to replace ob_end_clean() with ob_end_flush().
I'll change it again.
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();//Modify part
flush();
sleep(1);
}
?〉
After running it, do you find that $i is output once every second? Why is this?
Don't worry, let's take a look.
Open, search for output_buffering, and we will see settings like this, output_buffering = 4096. Just like its name output_buffering, the purpose of this setting is to buffer the output, with a buffer size of 4096bytes.
In our first piece of code, the reason why the output_buffering did not output as expected is because this output_buffering buffered all the outputs. If 4096bytes is not reached or the script is finished, the output will not be sent out.
The function of ob_end_clean() and ob_end_flush() in the second code is to terminate the buffering. In this way, you don't have to wait until there is a buffer of 4096bytes before it is sent out.
In the third paragraph of code, ob_flush() is used. Its function is to send the buffered data, but it will not terminate the buffering, so it must be used before each flush().
If we do not want to use ob_end_clean(), ob_end_flush() and ob_flush(), we must set the output_buffering in it to be small enough, for example, set to 0. It should be noted that if you plan to use ini_set("output_buffering","0") in your script to set it, then please stop, this method does not work. Because at the beginning of the script, the buffering settings are already loaded, and the buffering begins.
Maybe you will ask, since ob_flush() sends the buffered data, why do you still need to use flush()??? Isn't it possible to directly use the following code? ?
〈?php
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();
sleep(1);
}
?〉
Please note the difference between ob_flush() and flush(). The former releases data from the PHP buffer, while the latter sends data that is not in the buffer or is released to the browser. So when the buffer exists, we must use ob_flush() and flush() at the same time.
Is flush() indispensable here? No, we have another method, so that when there is data output, it will be sent to the browser immediately. The following two pieces of code do not require flush(). (When you set output_buffering to 0, you don’t even need ob_flush() and ob_end_clean())
〈?php
ob_implicit_flush(true);
for ($i=10; $i〉0; $i--)
{
echo $i;
ob_flush();
sleep(1);
}
?〉
〈?php
ob_end_clean();
ob_implicit_flush(true);
for ($i=10; $i〉0; $i--)
{
echo $i;
sleep(1);
}
?〉
Please pay attention to the above ob_implicit_flush(true). This function forces the output to immediately send to the browser whenever there is output. This way, there is no need to use flush() to send it to the browser after each output (echo).
The above complaints may not be valid in some browsers. Because browsers also have their own rules. I used Firefox1.5, IE6, opera8.5 to test it. Opera cannot output normally because it has a rule, that is, if you don’t encounter an HTML tag, you will definitely not output unless the script ends. FireFox and IE are quite normal.
Finally, a very interesting code is attached, the author is PuTTYshell. In a script cycle, each output will be overwritten by the previous output.
The following code is only available under firefox, and other browsers do not support the Content-Type of multipart/x-mixed-replace.
〈?php
header('Content-type: multipart/x-mixed-replace;boundary=endofsection');
print “\n--endofsection\n“;
$pmt = array(“-“, “\\“, “|“, “/“ );
for( $i = 0; $i 〈10; $i ++ ){
sleep(1);
print “Content-type: text/plain\n\n“;
print “Part $i\t“.$pmt[$i % 4];
print “--endofsection\n“;
ob_flush();
flush();
}
print “Content-type: text/plain\n\n“;
print “The end\n“;
print “--endofsection--\n“;
?〉