从Windows上的浏览器在后台运行PHP进程

时间:2012-07-30 20:27:46

标签: php

我有点遗憾地问这个,因为我知道之前已经多次询问过,但我找到的所有答案在我的情况下都不起作用。要么我做了一些根本错误的事情,要么我正在尝试做一些不可能的事情。

我需要能够从通过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);

完全不起作用 - 在尝试分叉新进程时挂起。

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

我知道我可以在数据库中将任务排队并批量运行,但是我需要在尽可能接近实时的情况下运行,所以不要因排队而引入更多延迟我只能这样做每分钟运行一次。

2 个答案:

答案 0 :(得分:0)

您可以尝试pcntl_fork功能。这可以分叉子进程(提供网页),同时继续在后台工作中完成剩余的工作。然而,需要谨慎使用它。只需阅读php.net文档,即可了解使用此方法的一些复杂性。

答案 1 :(得分: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()));

}