Progress bar not working flush - php

I got big problem, becouse i tested everything to make it works, but`s not - yet :)
i got simple for loop and there is a star, end, flush inside, but still my browser load all output at the and of loop, and i took for this question simple example:
<?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();
?>
a i`vd setup all about outpuuting_bufforing, zlib, gzib, and other alls. Exacly in htacces, script, file, even in php.ini, apache. I got dedicaded server so can configure what i need. Can some1 tell me what more can i try?
Ofc there is no error in any log file.
Thanks for advice !

The comments in the official PHP documentation for ob_flush() mention, that most browsers have an all-or-nothing approach to loading content. Therefore the browser will not show anything until the whole page is loaded.
See http://php.net/manual/de/function.ob-flush.php#109699
This means that flushing output to the browser will not work for you.
The alternative would be to start the initial request via AJAX and then use a second request to provide information about the current progess.

Related

Multiple flush statements in PHP and Apache

I' am using XMLHttpRequest 2 to get chunked response through it's onprogress event and displaying it in browser. Everything seems to work fine but I have a little confusion. Consider the following code:
<?php
echo "I' am sending ";
ob_flush();
flush();
echo "content to client.";
ob_flush();
flush();
This is pretty standard PHP way of sending chunked response to client. However I was expecting to get output as two different chunks, one containing first echo's result and other containing second's. But I' am getting a single combined chunk of both echo statements. When I put sleep(1) after first flush() then everything seems to work fine.
My question is that is there some deliberate wait on webserver side to wait for some other content before sending already received chunk or is there some thread scheduling mechanism that is forcing network layer of Apache to wait for it's turn.
Edit
I forgot to mention that I have disabled webserver's output buffering which means if I flush something from PHP it will get sent to browser.
Any help is highly appreciated.
Thanks.
See: http://www.icemelon.com/tutorials/20/Output_While_Script_Still_Running.htm
You may be seeing browser output buffering here. Try adding:
for($k = 0; $k < 40000; $k++)
echo ' ';
Right before you flush in order to fill up the browser's buffer and make it spit out your output.

making output buffer work

I have the following crazy snippet as a test ground for ob_start functionality.
ob_start();
for ($i = 1; $i <= 100000000; $i++) {
echo '<li>',$i, ' ',date("H:i:s");
ob_flush();
}
I wait minutes before I can see something on the screen.
For minutes, I look at a blank page with a status message "waiting for www.myserver.com" with a "loading..." message on the browser title.
Isn't ob_flush to prevent exactly this behaviour?
What do you do to the above snippet so that when you run it, you get an instant flow of text on your browser?
adding the line
flush();
right after the
ob_flush();
does the trick. browser shows the input instantly and you get a streaming text until the whole thing dumped on the browser or script times out.
DON'T TRY THIS SNIPPET CAUSE IT WOULD WASTE A LOT OF BANDWIDTH.
Does any one know why adding the flush() after the ob_flush make it happen?
NOTE THAT, just the flush() without the ob_flush() or just the ob_flush() without the flush() does not work.

How to echo in PHP while the script is still executing?

I developed a facebook application in PHP. The problem is that it takes 2 minutes to display the result. This might confuse the user, who sees a blank canvas and leaves.
I just want to echo a statement that it is still processing.
I tried flush(); and ob_flush(); and ob_start(); but it is of no use.
Is there any other simpler alternative to address my specific problem?
I tried this, but it did not work as well.
ob_implicit_flush(true);
ob_end_flush();
for ($i=0; $i<5; $i++) {
echo $i.'<br>';
sleep(1);
}
EDIT:
The above code works perfectly fine with IE and other Browsers.
Only Chrome has this issue.
Convert it to an AJAX request, where you load a quick page which can have anything you want, and then loads in data from the slower page in the background.
flush() won't do what you want because it will return only part of the output and the client will tend to wait for the complete page.
Call flush(); as often as required.
Unfortunately, this might or might not make the browser feel happy to display your stuff. Even on IE, the result isn't predictable.

Echo messages while php script still executes

I have a php script that uses cURL and takes about 10-15 minutes to execute. What it does, it parses about 1000 pages looking for specific matches and throughout the script I have diagnostic messages echo'ed out, like "Going to the next page", "Found a match", "Error loading page" ... The way it works now (and the way that it's normal) is it executes for like 10 minutes and only then spits out all my custom messages.
I would like to be able to display those messages as they happen, not when the script is done executing. I was thinking something like AJAX would do it, but am not sure how it would work. Any tips are greatly appreciated. Thanks.
So, this is a old post but I found a solution for this. As I also have to make the same thing, output when the script is still running. Not any answer from here helped.
First of all, I am using Win32 server(production) and XAMPP as local for tests. This example is just a proof of concept and can be modified as you please.
<?php
ob_implicit_flush(true);
for($i=1; $i<=10; $i++){
echo "$i ...<br>";
for($k = 0; $k < 40000; $k++) echo ' ';
sleep(1);
}
?>
So, we open output buffer as implicit. Then we make a demo loop to count from 1 to 10 and display the values as they are been processed. Second loop will fill in the browsers buffer. And finally to check if everything is working well we make a sleep for 1 second. Otherwise the script will run too fast and we could not know if we achieved the goal.
Hope this helps !
You could create a staging table.
The PHP script could, instead of echo'ing the message, store them into a database table (possibly memory table for performance).
You could then periodically poll a seperate PHP script using ajax, which would query the table, and return any new messages to the client.
Use flush to immediately send output to the browser, by flushing the output buffer.
echo "foo";
flush();
echo "bar";
flush();
Actually you're looking for something like flush and ob_flush, however bear in mind that there are a lot of factors that can prevent your output from being flush'd as it happens.
From the flush documentation you'll get:
Several servers, especially on Win32, will still buffer the output from your script until it terminates before transmitting the results to the browser.
Server modules for Apache like mod_gzip may do buffering of their own that will cause flush() to not result in data being sent immediately to the client.
I'm using the #ob_flush() after every echo. In this example PHP_EOL creates a new line after $string
function output($string){
echo $string.PHP_EOL;
#ob_flush();
}
Basically, have your script write HTML output to a temporary log file. Then use ajax to periodically update the end-user's browser with the temporary log file. jQuery will make quick work of this.
Ajax is the only guaranteed way to get it to work on all browsers. Here is a quote from PHP's flush page.
flush() may not be able to override
the buffering scheme of your web
server and it has no effect on any
client-side buffering in the browser.
It also doesn't affect PHP's userspace
output buffering mechanism. This means
you will have to call both ob_flush()
and flush() to flush the ob output
buffers if you are using those.
Sounds to be like you have output buffering turned on.
Calling ob_end_flush() will print what's currently in the buffer, and turn off the buffer for the rest of the script execution.
You can use the flush() function to send all the content of the buffer to the client. http://php.net/manual/fr/function.flush.php
You could use both flush and ob_flush, reminding to set the content type header:
<?php
header( 'Content-type: text/html; charset=utf-8' );
for( $i = 0 ; $i < 10 ; $i++ ){
echo $i . '<br>';
flush();
ob_flush();
sleep(1);
}
Source: dermeister note in php.net ob_flush page.
Tested on Firefox 42.0 and Chrome 46.0

PHP showing output of foreach to screen, for each item

One thing I have noticed with php, is that nothing is output to the screen until the script has stopped working. For the project I am working on I feed in a list of over 100 items and it performs a HTTP request for each item and when finished, shows a page with the status of each item, success failure etc.
What I want to know is if there is a way to output the results of each 'foreach' loop as they happen? So the user watching the screen sees the magic happening one line at a time or after say 5 lines.
I have only ever seen this done with Ajax type requests, is that what I should be looking to do instead maybe? Can anyone point me to a php function that does this or is it not possible?
It may be better to store all script output in a buffer then flush the buffer when required.
For example:
<?php
if (ob_get_level() == 0) ob_start();
$test = Array('one','two','three','four');
foreach ($test as $key=>$val)
{
echo $test;
ob_flush();
flush();
}
ob_end_flush();
?>
Make sure you have mod_gzip disabled!
flush() should do it, or you can look at all the output buffering functions
Use the flush() command
I use
flush(); #ob_flush();
after the output.

Categories