If you aren’t using the Apache module then using pcntl_fork() to fork a PHP process works fine. There are times when it would be really handy to perform a fork in PHP when it is running as an Apache module. There is a way to fake this, sort of.
Instead of forking your PHP script you can exec() another process to run in the background. This obviously isn’t the same as forking, but it is about as close as you can get when running as an Apache module. While reading through the comments on the PHP exec() page I was able to piece together enough information to make execing a background process work. Here’s an example:
exec("/usr/local/bin/myprog 2>/dev/null >&- < &- >/dev/null &”);
This will execute /usr/local/bin/myprog and redirect STDOUT and STDERR to /dev/null and run the process in the background. You can even pass arguments to your program like this:
$safe_arg["arg_1"] = escapeshellarg($arg_1);
$safe_arg["arg_2"] = escapeshellarg($arg_2);
exec(”/usr/local/bin/myprog {$safe_arg["arg_1"]} {$safe_arg["arg_2"]} 2>/dev/null >&- < &- >/dev/null &”);
Make sure that you escape any data you get from outside your script when using it in exec().
April 8th, 2006 at 9:54 am Breyten’s Dev Blog » Blog Archive » links for 2005-11-02
[...] Joseph Scott’s Blog » Fake Fork in PHP “here are times when it would be really handy to perform a fork in PHP when it is running as an Apache module. There is a way to fake this, sort of.” (tags: php) [...]
March 21st, 2007 at 6:26 am ferdhie
I’ve tried with ping, but the apache seems to wait for the request to return
exec(”ping yahoo.com 2>&1 1>/tmp/ping.log &”);
got any idea?
November 16th, 2007 at 10:32 pm Stephen Hosking
Thanks so much for this! I needed to create a background process and tried pcntl_fork, but couldn’t do it because I’m using Apache. So I was stuck, until I luckily hit this web page. That’s really great Unix work nutting out that command line! I fiddled with it a bit, and worked out 1. You do seem to need all those options - “&” is not enough, and 2. in ‘< &- ‘ the space is not necessary, ‘<&- ‘ works fine.
Thanks again!
June 11th, 2008 at 6:22 pm Daniel Molina
Sorry, but this isn’t a fork fake or similar such thing. The system call fork(2) — wrapped arround php with pcntl_fork() function — sets the entry point to the right line of source, instead your implementation that set the entry point to the start of the script.
Play a little with labels if you want the desired results. Also, see the way to save the environment and allocated variables… Be careful y you serialize the $GLOBALS variable.
June 23rd, 2008 at 3:45 am Observer
Another way to perform several tasks simultaneously is by using stream_select(). This is useful in the cases where you php script makes many requests to multiple other websites.
In one of my web scripts, I had to make up to 24 http requests. When I done it sequentially, it took over 1 minute. Now it takes less than 10 seconds. See it and test it here: http://www.info-express.org/website-popularity-checker
September 25th, 2008 at 6:52 am XSet » Blog Archive » Parallel Processing in PHP
[...] Of course in the LAMP development world a quick and dirty hack is often as good as a well rounded programmewd solution. Joseph Scott shows you how to use a Linux execution feature (namely forking a command into the background using and ampersand) to parallelise applications that don’t need to return anything. I’ve actually used this technique to build a one hit multiplexor for various applications: Quick and dirty fake fork for non returning scripts [...]