What You’re Doing Is Rather Desperate

Notes from the life of a bioinformatics researcher

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.

Written by nsaunders

January 12, 2007 at 9:43 pm

11 Responses

Subscribe to comments with RSS.

  1. Nice, just what I needed. Good to find it in a bioinformatics site/blog.

    Cheers

    PNuin

    March 10, 2007 at 7:50 am

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

    mike

    March 17, 2007 at 3:01 am

  3. Thanks a lot, found your code snippet just before starting to implement TFBS-search web-server.

    Bogdan

    May 24, 2007 at 12:42 am

  4. [...] Found a nicely illustrated method for running a background shell command from PHP and continuously checking if the process is still runnin…. [...]

  5. [...] What You’re Doing Is Rather Desperate is a very nice way of running a background task in PHP. I’ve implemented compression of a [...]

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

    Thanks
    Raj

    Raj

    July 26, 2007 at 8:58 am

  7. I don’t do Windoze, sorry. Try the PHP documentation – there are comments at the shell_exec() link in my post.

    nsaunders

    July 26, 2007 at 10:12 am

  8. [...] Running a background process in PHP « What You’re Doing Is Rather Desperate (tags: php process background shell) [...]

  9. 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.

    Scott

    November 29, 2007 at 1:31 pm

  10. 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

    ezequiel

    December 12, 2007 at 2:13 am

  11. [...] an article on running background jobs in php [...]


Comments are closed.