Well, I fully admit PHP is not the best language to write daemons, because of all the performance issues we all know, and infinite loops are not the most beautiful thing you can see in a procedural script. However, it may happen that for a reason X or Y, you want to use PHP to write daemons (it has even happened to me!).
These are my thoughts about this subject. Again, I read a lot of articles over the Internet, took the best of each, add some of my imagination, and made a set of functions and scripts to easily turn a PHP script into a daemon. For those who want the code right now, help yourself: PHP daemonizer
Warning 1: this post is not aimed to very beginners in PHP development or linux environments, if you’ve never heard about infinite loop, daemons or cron jobs, I suggest you come back here later 😛
Warning 2: i developed this for a Debian system, so I assume I can check if a process is running by checking the /proc/$PID file (if the file /proc/123 exists, it means that the process 123 is running). I’m also using PHP5-CLI, pcntl functions (that is present in most of the default installations) and cron jobs. If you can’t administrate your server, it’s gonna be difficult to do what follows…
Make a PHP script to run forever
First of all, what is daemon? It’s roughly a script that runs forever and normally never stops. However, when you execute a PHP script:
- it starts
- it does what it has to do
- it ends
You might already know the trick: using an infinite loop to do your stuff. However, you’re never sure your script is not gonna die at a time or another for a reason you didn’t expect (out of memory, exception, …), so you might want your script to start again when this situation happens.
The next step is to set a cron job to try to start the daemon again every minute in case it’s stopped, something like that:
* * * * * root cd /my/daemon/path && php daemon.php >>/var/log/daemon 2>&1
But you don’t want your daemon.php script to be run more than once at the same time. I so wrote a method to prevent it, at the top of your daemon.php script, just add the following line:
This _() method will:
- check if the daemon is already running by looking the process’ PID
- if it’s already running, make the script to die
- if it’s not, write its own PID in a file (that corresponds to the first argument of the method), and continue the script execution
We’re now assured that whatever happens, our daemon won’t be down more than one minute in case of failure, it’s not so bad. Moreover, you can use this not only to run daemon, but also to prevent a script to be executed more than one time at any moment.
I also wanted to give PHP a real daemon behavior by creating a starting script (like when your want to start/stop apache for example, you run a script like: /etc/init.d/apache start or /etc/init.d/apache stop).
You’ll find in the .zip a script to do that. Just copy/paste it to your /etc/init.d/ folder, you can even remove the .php extension to make the illusion perfect. Configure the 4 constants in the file to tell it about the daemon’s path, etc… And you’re done, you now can start, stop, restart and get the status of your daemon by calling the following scripts in your shell:
- /etc/init.d/myDaemon start
- /etc/init.d/myDaemon stop
- /etc/init.d/myDaemon restart
- /etc/init.d/myDaemon status
Download the full package here: PHP daemonizer
I don’t say my solution is the best, but I think it works properly in my case at least, on Debian systems. If you have any comments or bug reports, don’t hesitate.