Asynchronous shell exec in PHP


Answers

I used at for this, as it is really starting an independent process.

<?php
    `echo "the command"|at now`;
?>
Question

I've got a PHP script that needs to invoke a shell script but doesn't care at all about the output. The shell script makes a number of SOAP calls and is slow to complete, so I don't want to slow down the PHP request while it waits for a reply. In fact, the PHP request should be able to exit without terminating the shell process.

I've looked into the various exec(), shell_exec(), pcntl_fork(), etc. functions, but none of them seem to offer exactly what I want. (Or, if they do, it's not clear to me how.) Any suggestions?




I used this...

/** 
 * Asynchronously execute/include a PHP file. Does not record the output of the file anywhere.  
 * Relies on the PHP_PATH config constant.
 *
 * @param string $filename  file to execute
 * @param string $options   (optional) arguments to pass to file via the command line
 */ 
function asyncInclude($filename, $options = '') {
    exec(PHP_PATH . " -f {$filename} {$options} >> /dev/null &");
}

(where PHP_PATH is a const defined like define('PHP_PATH', '/opt/bin/php5') or similar)

It passes in arguments via the command line. To read them in PHP, see argv.




In Linux, you can start a process in a new independent thread by appending an ampersand at the end of the command

mycommand -someparam somevalue &

In Windows, you can use the "start" DOS command

start mycommand -someparam somevalue



I also found Symfony Process Component useful for this.

use Symfony\Component\Process\Process;

$process = new Process('ls -lsa');
// ... run process in background
$process->start();

// ... do other things

// ... if you need to wait
$process->wait();

// ... do things after the process has finished

See how it works in its GitHub repo.




You can also run the PHP script as daemon or cronjob: #!/usr/bin/php -q




To all Windows users: I found a good way to run an asynchronous PHP script (actually it works with almost everything).

It's based on popen() and pclose() commands. And works well both on Windows and Unix.

function execInBackground($cmd) {
    if (substr(php_uname(), 0, 7) == "Windows"){
        pclose(popen("start /B ". $cmd, "r")); 
    }
    else {
        exec($cmd . " > /dev/null &");  
    }
} 

Original code from: http://php.net/manual/en/function.exec.php#86329