Timed or delayed scripts in PHP

Many PHP developers believes, that PHP is purely request-response language, that can generate exactly one respone to each request. In other words, that it is impossible to write timed PHP scripts. The ones, that does something in portions and return many results to one request. Well, that is not quite true.

We can name few types of timed scripts (my own name):

  • script, that runs forever (until manually stopped) — i.e. some listener, data accuring script etc.
  • script, that runs at certain, repatable periods of time — i.e. some database management tools run once each night etc.
  • script, that is invoked once and returns many results — i.e. some multi-photo shrinker etc.

To solve first problem you need either PHP daemon (dedicated, properly configured server) or be able to run any standard PHP script as daemon task. Consider PHP Daemon, this Stack Overflow question and answers to it or any other source, that talks about running PHP script as daemon.

For second task, you most likely need access to CRON or similar solutions. Consider some interesting answers to this Stack Overflow question or many more sources about CRON.

And as for third kind of times script, all you need is to operate on output buffering mechanism in PHP. Here is the very basic example. It prints ten Line to show lines, each with 2 seconds separation:

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();

As you can see, this script is able to send more than one result to the browser, though it initiated it with only one request. Possibilities are endless. You can for example use this technique to parse more than one object (file, URL, database result) and keep user informed, that your script is not dead, that it is still working and even show any kind of progress.

The only side effect, that you have to accept, is that your browser technically won’t mark request as endend until very last cycle. This means, that a round circle (or any other way to represent, that page is loading) won’t stop for the entire process of timed execution of your script.

Leave a Reply