How To Create A PHP Daemon – Simple Examples

Welcome to a quick tutorial and example of how to create a PHP daemon. Need to run a “service” PHP script in the background? Send out emails, fetch updates, or monitor something?

  • PHP does not support daemons natively.
  • But we can simulate a daemon by creating a script that runs infinitely – while (true) { /* DO SOMETHING */ sleep(1); }
  • Then set it to run in the command line – PHP DAEMON.PHP

Yes, it’s that simple. Let us walk through a few more examples in this guide – Read on!

ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.

 

 

TABLE OF CONTENTS

Download & Notes Simple Daemon Useful Bits & Links
The End

 

DOWNLOAD & NOTES

Firstly, here is the download link to the example code as promised.

 

EXAMPLE CODE DOWNLOAD

Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

QUICK NOTES

If you spot a bug, please feel free to comment below. I try to answer questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

 

SIMPLE DAEMON EXAMPLES

All right, let us now get into the simple examples of PHP daemons.

 

1) BASIC MECHANICS

1-basic.php
<?php
// (A) CHECK
if (PHP_SAPI != "cli") {
  exit("Please run this script from the command line");
}

// (B) SETTINGS
$cycle = 10; // WAIT 10 SECS BETWEEN CYCLES
 
// (C) RUN
while (true) {
  echo "It works!" . PHP_EOL;
  sleep($cycle);
}

Yep, that’s all for the “basics” of a “daemon” in PHP. Just run this script in the command line PHP 1-basic.php, and it will output It works! every 10 seconds… Not very useful, so let’s go through more practical examples below.

 

 

2) FETCH DATA

2a-fetch.php
<?php
// (A) CHECK
if (PHP_SAPI != "cli") {
  exit("Please run this script from the command line");
}

// (B) SETTINGS
$cycle = 10; // WAIT 10 SECS BETWEEN CYCLES
$url = "http://localhost/2b-dummy.txt"; // DUMMY SERVER

// (C) RUN
while (true) {
  // (C1) CURL INIT
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL, $url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
 
  // (C2) FETCH UPDATES FROM DUMMY SERVER
  $result = curl_exec($ch);
  if (curl_errno($ch)) {
    echo curl_error($ch) . PHP_EOL;
  } else {
    echo $result . PHP_EOL;
  }
  curl_close($ch);
 
  // (C3) UPDATE DATABASE
  $result = json_decode($result, true);
  // $sql = "UPDATE `rates` SET `EUR` = ?";
  // $sql = "UPDATE `rates` SET `GBP` = ?";
  unset($result);
 
  // (C4) WAIT FOR NEXT CYCLE
  sleep($cycle);
}

2b-dummy.txt
{"EUR":1.17,"GBP":1.38}

In this example, we are:

  • Using CURL to periodically fetch the exchange rate for EUR-USD and GBP-USD from a dummy server.
  • Then update the rates in the local database.

Yep, this is a potentially good one for e-commerce websites that deal with multiple currencies.

P.S. We can also use CURL to check if there is a response from another server, use it for monitoring.

 

 

3) GENERATING REPORTS

3-report.php
<?php
// (A) CHECK
if (PHP_SAPI != "cli") {
  exit("Please run this script from the command line");
}
 
// (B) SETTINGS
$cycle = 1; // WAIT 10 SECS BETWEEN CYCLES
$per = 10; // WRITE 10 ENTRIES PER CYCLE
 
// (C) RUN
while (true) {
  // (C1) CHECK FOR REPORTS TO WRITE
  // THIS SHOULD CHECK AGAINST A DATABASE TABLE
  // BUT WE JUST USE DUMMY FLAGS HERE
  if (!isset($current)) {
    $current = 0; 
    $entries = 100; // DUMMY - 100 ENTRIES TO WRITE
    $file = "report.csv"; // REPORT FILE
  }

  if ($current < $entries) {
    // (C2) CREATE/OPEN FILE
    if ($current == 0) { $fh = fopen($file, "w"); }
    else { $fh = fopen($file, "a"); }

    // (C3) WRITE TO FILE
    // WE WILL NORMALLY USE SELECT SQL QUERY TO FETCH DATA HERE
    // BUT WE JUST WRITE A NUMBER FOR THIS DUMMY EXAMPLE
    $i = 0;
    while ($current < $entries) {
      $current++; $i++;
      fwrite($fh, "$current,$current\r\n");
      echo $current . PHP_EOL;
      if ($i==$per) { break; }
    }
    fclose($fh);
    
    // (C4) DONE!
    if ($current == $entries) {
      // mail("admin@mail.com", "DONE", "Report generation complete");
      echo "Report generation complete";
    }
  }

  // (C5) NEXT CYCLE
  sleep($cycle);
}

Have to generate a huge report? That will probably break the server if it runs continuously? Here’s how we can potentially break it into “multiple mini sections”, and send an email to the administrator when the generation is complete.

 

 

USEFUL BITS & LINKS

That’s all for this tutorial, and here is a small section on some extras and links that may be useful to you.

 

LIMITATIONS

As you may have already guessed, this method will permanently take up one process thread. While some people may flip out at the idea of an infinite loop, but it works – It is at least good for the people who don’t have access to install a PHP extension on the server. Most importantly, it is very easy to implement.

 

RUN AT STARTUP

It will be a pain to manually run the script every time, so here is how we schedule it to run at startup instead:

 

SCHEDULED SCRIPTS

Not too keen on an infinite while loop? Here is how to schedule scripts to run at a fixed time or interval instead:

How to Schedule PHP Script to Run At Specified Time

 

LINKS & REFERENCES

If you are looking for a more “solid” solution, do check out the following –

 

INFOGRAPHIC CHEAT SHEET

Simple PHP Daemon (click to enlarge)

 

THE END

Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!

2 thoughts on “How To Create A PHP Daemon – Simple Examples”

    1. I can’t remember the exact steps and commands, but basically, run the PHP like a background process. In Linux, it goes something like nohup php SCRIPT.php > /dev/null. As for Windows, I remember using PHP to spawn another “silent command”, something like pclose(popen('start /B php.exe SCRIPT.php));.

Leave a Comment

Your email address will not be published. Required fields are marked *