0

我很抱歉问这个问题,因为我知道以前在这里已经问过很多次了,但是我找到的所有答案都不适用于我的情况。要么我在做一些根本错误的事情,要么我正在尝试做一些不可能的事情。

我需要能够从通过 Web 浏览器访问的 PHP 文件(由在 Windows 上运行的 Apache Web 服务器提供服务)中分叉一个后台进程。我需要前台进程完成,因此浏览器停止等待服务器,而分叉进程在后台继续。我正在使用 PHP 5.3。

我尝试了许多建议的解决方案,但都失败了:

shell_exec('D:\php5.3\php.exe sleep.php > out 2>out2' );

无论是通过命令行运行,还是通过浏览器运行,前台进程都没有完成,直到后台完成。最后添加一个“&”似乎没有任何区别

pclose(popen("start D:\php5.3\php.exe sleep.php","r"));

这个通过命令行运行良好,但是当通过浏览器访问时,它等待前台和后台进程完成。

exec("nohup D:/php5.3/php.exe -f sleep.php > out 2>out2");

这似乎根本不起作用

$commandString = "start /b D:/php5.3/php.exe d:\\webroot\\other\\tests\\sleep.php"; 
pclose(popen($commandString, 'r'));

在命令行中工作,在浏览器中等待

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("D:/php5.3/php-win.exe -f d:\\webroot\\other\\tests\\sleep.php", 0, false);

根本不起作用 - 尝试分叉新进程时挂起。

任何人都可以帮忙吗?我错过了一些非常明显的东西吗?

我知道我可以将任务排队在数据库中并批量运行,但我需要它尽可能接近实时地运行,所以不想通过排队来引入更多延迟,然后我只能运行一次 max一分钟。

4

2 回答 2

0

即使这篇文章已经过时,但可能对其他人有用,这对我有用,花了几个小时才找到解决方案!

function execInBack($phpscript, $args = array(), $logfile = '', $stdoutfile = '') {
if (count($args) == 0) {
    $args[] = md5(mt_rand());
}

$arg = '';

foreach ($args as $a) {
    $arg .= "\"$a\" ";
}

$cmd = "start /b c:\php\php5.3.10\php.exe ./$phpscript $arg";
$p = array();

$desc = array();
if ($logfile && $stdoutfile) {
    $desc = array(
        1 => array("file", $stdoutfile, "w"),
        2 => array("file", $logfile, "a")
    );
}

proc_close(proc_open($cmd, $desc, $p, getcwd()));

}

于 2014-01-04T03:09:35.190 回答
0

您可以尝试 pcntl_fork 函数。这可以派生一个子进程(为网页服务),同时继续在后台完成其余的工作。然而,这是需要谨慎使用的东西。只需阅读 php.net 文档以了解使用此方法的一些复杂性。

于 2012-07-30T20:37:38.527 回答