Running a background process in PHP

In an ideal world, all of the functions that you need would be available in the language of your choice. This is rarely the case for bioinformatics projects, where it’s often convenient or necessary to run a script or program outside your main script, grab the results and parse them. Easy enough – but if you’re writing a web application and the external program takes longer than a few seconds to run, you’re faced with a blank web page and confused users. Normally, the page loads only after all associated processes are complete.

So you’d like to run your external program in the background and display a reassuring message that says “Analysing sequence. . .”, or something similar. Here’s how you do that in PHP.

The PHP function that you need is shell_exec(). PHP has excellent online documentation: here’s the shell_exec() entry. A kind user has provided us with 2 functions for use under Linux: one for running a background process, another for monitoring a running process. I’ve edited them slightly and present them below:

   function run_in_background($Command, $Priority = 0)
   {
       if($Priority)
           $PID = shell_exec("nohup nice -n $Priority $Command 2> /dev/null & echo $!");
       else
           $PID = shell_exec("nohup $Command 2> /dev/null & echo $!");
       return($PID);
   }
   function is_process_running($PID)
   {
       exec("ps $PID", $ProcessState);
       return(count($ProcessState) >= 2);
   }

To run something like hmmsearch from the HMMER package, you'd do this:

echo("Running hmmsearch. . .")
$ps = run_in_background("hmmsearch $hmmfile $fastafile > $outfile");
  while(is_process_running($ps))
   {
     echo(" . ");
       ob_flush(); flush();
            sleep(1);
   }

This will run hmmsearch in the background, printing "Running hmmsearch. . ." to the screen, followed by " . " once a second, until done.

There's a small "gotcha" to look out for if you pass command line arguments to a perl script from PHP. You need to quote the arguments - otherwise PHP can't get $PID from the shell and you'll get the blank screen, confused user effect:

echo("Running funky Perl. . .")
$ps = run_in_background("perl FunkyPerl.pl '$infile'");
  while(is_process_running($ps))
   {
     echo(" . ");
       ob_flush(); flush();
            sleep(1);
   }

Incidentally, quoting arguments is a good idea in general - you know, in case your users upload files with names like "gi|12345|abcde|" and your web app tries to write to file "gi|12345|abcde|.outfile"...

That's about all there is to it.

11 thoughts on “Running a background process in PHP

  1. mike

    thats what i need: $PID = shell_exec(“nohup nice -n $Priority $Command 2> /dev/null & echo $!”); :))
    cheers

  2. Pingback: Executing and checking background shell process from PHP » Autarchy of the Private Cave

  3. Pingback: Richy’s Random Ramblings / Techy: Background Processes In PHP

  4. Raj

    What do I need to do to make this work on windows? The function doesn’t return process ID; returns $! instead.

    Thanks
    Raj

  5. Pingback: links for 2007-08-28 : Daniel Costa

  6. Scott

    I found running PHP5 on mac 10.5 that I had to change
    $PID = shell_exec(“nohup $Command 2> /dev/null & echo $!”);
    to
    $PID = shell_exec(“nohup $Command > /dev/null 2> /dev/null & echo $!”);

    In order to get it to run in the background.

  7. ezequiel

    I found running PHP5 on UBUNTU linux that I had to change
    $PID = shell_exec(”nohup $Command 2> /dev/null & echo $!”);
    to
    $PID = shell_exec(”nohup $Command > /dev/null 2> /dev/null & echo $!”);

    In order to get it to run in the background.
    ps: thanks scott for the extra tip

  8. Pingback: php batch processing articles - tsuuhou

Comments are closed.