Ada*_*utt 195 php shell asynchronous
我有一个需要调用shell脚本的PHP脚本,但根本不关心输出.shell脚本会进行大量的SOAP调用,并且完成起来很慢,因此我不想在等待回复时减慢PHP请求的速度.实际上,PHP请求应该能够在不终止shell进程的情况下退出.
我已经研究过的各种exec(),shell_exec(),pcntl_fork(),等功能,但他们都不似乎提供正是我想要的.(或者,如果他们这样做,我不清楚如何.)有什么建议吗?
war*_*ren 214
如果它"不关心输出",那么脚本的exec是否可以&通过后台进程调用?
编辑 - 结合@AdmTheHut评论到这篇文章的内容,您可以将其添加到以下呼叫exec:
" > /dev/null 2>/dev/null &"
Run Code Online (Sandbox Code Playgroud)
这会将stdio(第一个>)和stderr(2>)重定向到/dev/null后台并在后台运行.
还有其他方法可以做同样的事情,但这是最简单的阅读.
上述双重定向的替代方法:
" &> /dev/null &"
Run Code Online (Sandbox Code Playgroud)
Czi*_*imi 52
我曾经在这一点,因为它是真正开始独立的进程.
<?php
`echo "the command"|at now`;
?>
Run Code Online (Sandbox Code Playgroud)
Luc*_*caM 25
对于所有Windows用户:我找到了运行异步PHP脚本的好方法(实际上它适用于几乎所有内容).
它基于popen()和pclose()命令.在Windows和Unix上都能很好地工作.
function execInBackground($cmd) {
if (substr(php_uname(), 0, 7) == "Windows"){
pclose(popen("start /B ". $cmd, "r"));
}
else {
exec($cmd . " > /dev/null &");
}
}
Run Code Online (Sandbox Code Playgroud)
原始代码来自:http://php.net/manual/en/function.exec.php#86329
Dar*_*ein 19
在linux上,您可以执行以下操作:
$cmd = 'nohup nice -n 10 php -f php/file.php > log/file.log & printf "%u" $!';
$pid = shell_exec($cmd);
Run Code Online (Sandbox Code Playgroud)
这将在命令提示符处执行命令,然后只返回PID,您可以检查> 0以确保其有效.
这个问题很相似:PHP有线程吗?
在Linux中,您可以通过在命令末尾附加一个&符来在新的独立线程中启动进程
mycommand -someparam somevalue &
Run Code Online (Sandbox Code Playgroud)
在Windows中,您可以使用"启动"DOS命令
start mycommand -someparam somevalue
Run Code Online (Sandbox Code Playgroud)
我用过这个...
/**
* 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 &");
}
Run Code Online (Sandbox Code Playgroud)
(其中PHP_PATH定义为类似define('PHP_PATH', '/opt/bin/php5')或类似的常量)
它通过命令行传递参数。要在 PHP 中阅读它们,请参阅argv。
小智 5
正确的方式(!)来做到这一点
fork forks,setsid告诉当前进程成为主进程(没有父进程),execve告诉调用进程被被调用进程替换.这样父母可以在不影响孩子的情况下退出.
$pid=pcntl_fork();
if($pid==0)
{
posix_setsid();
pcntl_exec($cmd,$args,$_ENV);
// child becomes the standalone detached process
}
// parent's stuff
exit();
Run Code Online (Sandbox Code Playgroud)
我还发现Symfony Process Component对此很有用。
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
Run Code Online (Sandbox Code Playgroud)
在其GitHub 存储库中查看它是如何工作的。