我有一个PHP脚本,需要调用shell脚本,但根本不关心输出。shell脚本执行了许多SOAP调用,完成起来很慢,因此我不想在PHP请求等待应答时降低它的速度。事实上,PHP请求应该能够在不终止shell进程的情况下退出。

我已经研究了各种exec()、shell_exec()、pcntl_fork()等函数,但它们似乎都不能提供我想要的东西。(或者,即使他们这样做,我也不清楚是如何做到的。)有什么建议吗?


当前回答

我用这个…

/** 
 * 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 &");
}

(PHP_PATH是一个const类型,如define('PHP_PATH', '/opt/bin/php5')或类似定义)

它通过命令行传入参数。要在PHP中读取它们,请参阅argv。

其他回答

我还发现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

在GitHub回购中查看它是如何工作的。

我不能使用>/dev/null 2>/dev/null &在Windows上,所以我使用proc_open代替。我在Windows 11上运行PHP 7.4.23。

这是我的代码。


function run_php_async($value, $is_windows)
{
    if($is_windows)
    {
        $command = 'php -q '.$value." ";
        echo 'COMMAND '.$command."\r\n";
        proc_open($command, [], $pipe);    
    }
    else
    {
        $command = 'php -q '.$value." > /dev/null 2>/dev/null &";
        echo 'COMMAND '.$command."\r\n";
        shell_exec($command);    
    }
}
$tasks = array();

$tasks[] = 'f1.php';
$tasks[] = 'f2.php';
$tasks[] = 'f3.php';
$tasks[] = 'f4.php';
$tasks[] = 'f5.php';
$tasks[] = 'f6.php';

$is_windows = true;

foreach($tasks as $key=>$value)
{
    run_php_async($value, $is_windows);
    echo 'STARTED AT '.date('H:i:s')."\r\n";
}

在每个要执行的文件中,我放了这个延迟:

<?php
sleep(mt_rand(1, 10));
file_put_contents(__FILE__.".txt", time());

所有文件都是异步执行的。

我用这个…

/** 
 * 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 &");
}

(PHP_PATH是一个const类型,如define('PHP_PATH', '/opt/bin/php5')或类似定义)

它通过命令行传入参数。要在PHP中读取它们,请参阅argv。

在Linux中,您可以通过在命令末尾附加&号来在一个新的独立线程中启动一个进程

mycommand -someparam somevalue &

在Windows系统中,可以使用“start”DOS命令

start mycommand -someparam somevalue

我发现唯一对我有效的方法是:

shell_exec('./myscript.php | at now & disown')