I know this is an old thread, but it looks like it can use a more complete answer. This is how I usually run several processes in PHP.
A word of caution: PHP was supposed to die. Meaning, the language was designed for a few seconds, and then exit. Although garbage cleaning in PHP has come a long way, be careful. Control your processes for unexpected memory usage or other weird things. Watch everything like a hawk until you install it and forget about it, and even then, still check the processes once in a while or automatically let them know that something is wrong.
As I typed this, it seemed like a good idea to pat him on github too.
When you are ready to run the program, I recommend doing the -f tail in the log to see the result.
<?php /* * date: 27-sep-2015 * auth: robert smith * info: run a php daemon process * lic : MIT License (see LICENSE.txt for details) */ $pwd = realpath(""); $daemon = array( "log" => $pwd."/service.log", "errorLog" => $pwd."/service.error.log", "pid_file" => $pwd."/", "pid" => "", "stdout" => NULL, "stderr" => NULL, "callback" => array("myProcessA", "myProcessB") ); /* * main (spawn new process) */ foreach ($daemon["callback"] as $k => &$v) { $pid = pcntl_fork(); if ($pid < 0) exit("fork failed: unable to fork\n"); if ($pid == 0) spawnChores($daemon, $v); } exit("fork succeeded, spawning process\n"); /* * end main */ /* * functions */ function spawnChores(&$daemon, &$callback) { // become own session $sid = posix_setsid(); if ($sid < 0) exit("fork failed: unable to become a session leader\n"); // set working directory as root (so files & dirs are not locked because of process) chdir("/"); // close open parent file descriptors system STDIN, STDOUT, STDERR fclose(STDIN); fclose(STDOUT); fclose(STDERR); // setup custom file descriptors $daemon["stdout"] = fopen($daemon["log"], "ab"); $daemon["stderr"] = fopen($daemon["errorLog"], "ab"); // publish pid $daemon["pid"] = sprintf("%d", getmypid()); file_put_contents($daemon["pid_file"].$callback.".pid", $daemon["pid"]."\n"); // publish start message to log fprintf($daemon["stdout"], "%s daemon %s started with pid %s\n", date("YMd H:i:s"), $callback, $daemon["pid"]); call_user_func($callback, $daemon); // publish finish message to log fprintf($daemon["stdout"], "%s daemon %s terminated with pid %s\n", date("YMd H:i:s"), $callback, $daemon["pid"]); exit(0); } function myProcessA(&$daemon) { $run_for_seconds = 30; for($i=0; $i<$run_for_seconds; $i++) { fprintf($daemon["stdout"], "Just being a process, %s, for %d more seconds\n", __FUNCTION__, $run_for_seconds - $i); sleep(1); } } function myProcessB(&$daemon) { $run_for_seconds = 30; for($i=0; $i<$run_for_seconds; $i++) { fprintf($daemon["stdout"], "Just being a process, %s, for %d / %d seconds\n", __FUNCTION__, $i, $run_for_seconds); sleep(1); } } ?>