Echo messages while php script still executes

15,226

Solution 1

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 !

Solution 2

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.

Solution 3

Use flush to immediately send output to the browser, by flushing the output buffer.

echo "foo";
flush();
echo "bar";
flush();

Solution 4

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.

Solution 5

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();
}
Share:
15,226
pHelics
Author by

pHelics

Updated on June 18, 2022

Comments

  • pHelics
    pHelics almost 2 years

    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.

  • Poelinca Dorin
    Poelinca Dorin over 13 years
    what if there will be 1000 users accessing the page at the same time with different parameters ? , you'll need to write 1000 files , i don't see this as an option .
  • mrbinky3000
    mrbinky3000 over 13 years
    You can easily create temp files in PHP. Its basically the same as a 1000 users INSERT'ing stuff into a mysql database. Heck, use, mysql. Just store a log someplace and tie it to that session if more than one person is using it. I have a feeling this is a backend script to be used by a single person.
  • mrbinky3000
    mrbinky3000 over 13 years
    Flush is not guaranteed to work across all browsers / platforms / configurations
  • mrbinky3000
    mrbinky3000 over 13 years
    Agreed. Flush will not work 100% of the time. Ajax is needed.
  • pHelics
    pHelics over 13 years
    You made a good point, until the script is done I'm working on it on Win32 platform, then I'll put it to unix
  • richardaum
    richardaum over 9 years
    Isn't there a push-like solution (instead of polling)?