Skuli Axelson
Skuli Axelson

Reputation: 524

PHP while with sleep loop not updating database until end of loop

I have a while loop with a sleep function that I wan´t to run -> update database -> sleep -> run again for a number of 10 times. With the below script the script loops 10 times, but it only updates the database when all 10 loops have finished.

I added an echo at the end just to verify, and the echo does not appear on the page until the and when every loop is echoed out at once.

I have also tried placing ob_flush() and flush() after the echo with no luck.

Script

$loops = 10;
while ($loops > 0)
{
  while($row = mysql_fetch_array($result))
  {
    // Get current User status
    $username = $row['username'];
    $user_status = $row['user_status'];
    $user_updated = date('Y-m-d H:i:s');

    // Update database
    $update_sql = "UPDATE  `database`.`user` SET  `user_status` =  '$user_status',
                                                  `user_updated` =  '$agent_updated'
                                            WHERE  
                                                  `user`.`username` =  '$username'";
    $update=mysql_query($update_sql);
    echo "Loop #".$loops."<br>";
  }
flush();
$loops--;
Sleep(5);
}

I've also tried the same with a FOR loop.
Any suggestions would be appreciated. I've gone through the search and haven´t found users with similar issues but I couldn't find the answer.

Upvotes: 0

Views: 4209

Answers (3)

Skuli Axelson
Skuli Axelson

Reputation: 524

As pointed out by N.B. that PHP only returns results all at once after the script runs, I have ended with the following solution:

A bash.sh script that runs the PHP page every 5 seconds:

#!/bin/bash

set -e
count=1
while [ $count -le 12 ] :
do
  # run this scripts for one minute (12 times every 5 seconds = 60 seconds)
  /usr/bin/php -q thescript.php
  (($count++))
sleep 5
done

Then a cronjob that runs the page every minute. The above works and solves my issue.

Upvotes: 0

jcjr
jcjr

Reputation: 1503

It seems, according to the code provided, that all updates are done in the first loop, then mysql_fetch_array($result) returns only falses and the inner loop is not proceeded again in the other main loops, unless you fill $result again (between while cycle headers).

Upvotes: 1

Aitor Calderon
Aitor Calderon

Reputation: 773

You can get those echoes to show one by one, but on a controlled environment (according to php documentation, flush may still buffer the output on several Win32 systems), you can read further in the php flush manual page.

To be more specific, make sure APaches mod_gzip is disabled, also, some php.ini settings like output_buffering and zlib.output_compression should be set to false.

output_buffering = false
zlib.output_compression = false

Even with all of this, you may also need to send a "big" amount of data (like 2048 chars) in order to make some browser to actually display new data.

echo "One"
echo str_repeat(" ", 2048);
Sleep(3)
echo "Two"
echo str_repeat(" ", 2048);
// Ans so on

In the comments of the aforementioned manual page, you can see more examples.

Upvotes: 1

Related Questions