I need to run a php script as daemon process (wait for instructions and do stuff). cron job will not do it for me because actions need to be taken as soon as instruction arr
Kevin van Zonneveld wrote a very nice detailed article on this, in his example he makes use of the System_Daemon PEAR package (last release date on 2009-09-02).
I recently had a need for a cross-platform solution (Windows, Mac, and Linux) to the problem of running PHP scripts as daemons. I solved the problem by writing my own C++ based solution and making binaries:
https://github.com/cubiclesoft/service-manager/
Full support for Linux (via sysvinit), but also Windows NT services and Mac OSX launchd.
If you just need Linux, then a couple of the other solutions presented here work well enough and, depending on the flavor. There is also Upstart and systemd these days, which have fallbacks to sysvinit scripts. But half of the point of using PHP is that it is cross-platform in nature, so code written in the language has a pretty good chance of working everywhere as-is. Deficiencies start showing up when certain external native OS-level aspects enter the picture such as system services, but you'll get that problem with most scripting languages.
Attempting to catch signals as someone here suggested in PHP userland is not a good idea. Read the documentation on pcntl_signal()
carefully and you will quickly learn that PHP handles signals using some rather unpleasant methods (specifically, 'ticks') that chew up a bunch of cycles for something rarely seen by processes (i.e. signals). Signal handling in PHP is also only barely available on POSIX platforms and support differs based on the version of PHP. It initially sounds like a decent solution but it falls pretty short of being truly useful.
PHP has also been getting better about memory leak issues as time progresses. You still have to be careful (the DOM XML parser tends to leak still) but I rarely see runaway processes these days and the PHP bug tracker is pretty quiet by comparison to the days of yore.
If you can - grab a copy of Advanced Programming in the UNIX Environment. The entire chapter 13 is devoted to daemon programming. Examples are in C, but all the function you need have wrappers in PHP (basically the pcntl and posix extensions).
In a few words - writing a daemon (this is posible only on *nix based OS-es - Windows uses services) is like this:
SIGHUP
(usually this is ignored or used to signal the daemon to reload its configuration) and SIGTERM
(to tell the process to exit gracefully).fork()
again and have the parent exit.stdin
, stdout
and stderr
and don't write to them. The corrrect way is to redirect those to either /dev/null
or a file, but I couldn't find a way to do it in PHP. It is possible when you launch the daemon to redirect them using the shell (you'll have to find out yourself how to do that, I don't know :).Also, since you are using PHP, be careful for cyclic references, since the PHP garbage collector, prior to PHP 5.3, has no way of collecting those references and the process will memory leak, until it eventually crashes.
Extending Emil Ivaov answer, You can do the following to close STDIN, STDOUT AND STDERROR in php
if (!fclose(STDIN)) {
exit("Could not close STDIN");
}
if (!fclose(STDOUT)) {
exit("Could not close STDOUT");
}
if (!fclose(STDERR)) {
exit("Could not close STDERR");
}
$STDIN = fopen('/dev/null', 'r');
$STDOUT = fopen('/dev/null', 'w');
$STDERR = fopen('/var/log/our_error.log', 'wb');
Basically you close the standard streams so that PHP has no place to write. The following fopen
calls will set the standard IO to /dev/null
.
I have read this from book of Rob Aley - PHP beyond the web
You can
nohup
as Henrik suggested.screen
and run your PHP program as a regular process inside that. This gives you more control than using nohup
. I'd recommend the simplest method (screen in my opinion) and then if you want more features or functionality, move to more complex methods.
you can check pm2 here is, http://pm2.keymetrics.io/
create a ssh file, such as worker.sh put into your php script that you will deal with.
worker.sh
php /path/myscript.php
daemon start
pm2 start worker.sh
Cheers, that is it.