Asynchronous shell exec in PHP

2018-12-31 04:13发布

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?

13条回答
琉璃瓶的回忆
2楼-- · 2018-12-31 04:39

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.

查看更多
君临天下
3楼-- · 2018-12-31 04:41

php-execute-a-background-process has some good suggestions. I think mine is pretty good, but I'm biased :)

查看更多
不再属于我。
4楼-- · 2018-12-31 04:42

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

查看更多
余欢
5楼-- · 2018-12-31 04:45

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.

查看更多
心情的温度
6楼-- · 2018-12-31 04:46

If it "doesn't care about the output", couldn't the exec to the script be called with the & to background the process?

EDIT - incorporating what @AdamTheHut commented to this post, you can add this to a call to exec:

" > /dev/null 2>/dev/null &"

That will redirect both stdio (first >) and stderr (2>) to /dev/null and run in the background.

There are other ways to do the same thing, but this is the simplest to read.


An alternative to the above double-redirect:

" &> /dev/null &"
查看更多
临风纵饮
7楼-- · 2018-12-31 04:49

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
查看更多
登录 后发表回答