PHP在Windows Wampserver环境下如何将exec()作为后台进程运行

26

我正在尝试设置一个PHP触发器文件,以启动后台进程(参见这个问题)。

我在Windows Wampserver环境下进行这个操作。

例如,我有一个trigger.php文件,运行exec函数来调用我的backgroundProcess.php进行解析和执行。

然而问题是,我的trigger.php文件需要等待exec()命令完成运行backgroundProcess.php,然后才会停止。后台进程运行大约20-30秒,trigger.php在此期间一直等待,直到backgroundProcess.php完全结束。

这有意义吗?这是运行exec()命令的trigger.php文件:

exec('C:\wamp\bin\php\php'.phpversion().'\php.exe -f C:\path\to\backgroundProcess.php > C:\wamp\bin\php\php'.phpversion().'\dev\null &');
基本上,我想让trigger.php仅触发后台进程,而不等待其完成。

这个问题一直以来都是随机出现的,会抛出无法运行命令的异常。请检查我的答案。 - Muhammad Gelbana
文件backgroundProcess.php里面是什么? - user3120717
6个回答

26

使用以下命令解决了问题:

$WshShell = new COM("WScript.Shell");
$oExec = $WshShell->Run("C:\wamp\bin\php\phpVERSIONNUMBER\php-win.exe -f C:/wamp/www/path/to/backgroundProcess.php", 0, false);

这个问题一直以来都是随机出现的,会抛出无法运行命令的异常。请检查我的答案。 - Muhammad Gelbana
1
@Muhammad Gelbana,你在这个问题中没有回答。能否更具体一些,或者链接到你所指的答案? - computrius
2
它被删除了!不管怎样,这里是我写的摘要: exec("CMD /C start yourcommand here"); 我认为/C参数开关并不是必要的,但我只是额外确认一下。如果您想在脚本当前目录中执行,请在命令前加上dirname(FILE)。只有当start命令存在于您的Windows机器上时,才能实现此功能。 - Muhammad Gelbana

10

尝试在运行PHP 5.2.8的Windows 2000服务器上实现相同的操作。

但是这些解决方案都不适用于我,PHP一直在等待响应。

最终找到的解决方案是:

$cmd = "E:\PHP_folder_path\php.exe E:\some_folder_path\backgroundProcess.php";
pclose(popen("start /B ". $cmd, "a"));  // mode = "a" since I had some logs to edit

PS:由于这两个链接在研究此问题时帮了我很多忙,因此我将相同的回复贴到另一个主题中(PHP on a windows machine; Start process in background)。


我发现在运行PHP 5.4的Win7上,这种方法非常可靠。 - JoshuaDavid
a不是popen()的有效模式,只有rw或二进制的rbrw被接受。 - Milad Abooali

4

@JohnP - 是的,但我认为我在结尾处使用了> C:\wamp\bin\php\php'.phpversion().'\dev\null &来实现这一点? - Emmanuel
我认为你需要创建一个文件描述符并将其作为第二个参数传递。不仅仅是管道它。 - JohnP
@JohnP - 我之前没有听说过文件描述符... 至少不是这个术语。你能举个快速的例子吗? - Emmanuel
这只是一个指向文件的指针。$fd = fopen('dump.txt', 'a')。fd 只是一个花哨的术语 :) - JohnP
@JohnP - 不,添加文件描述符没有起作用。但是我想出了其他办法,问题解决了!请参见上面的编辑 :) - Emmanuel
@Emmanuel,哦?嗯,也许这是一个Windows的问题。我认为COM只能在Windows上工作。另外,如果它对你有用,我认为你应该将其发布为答案并标记为已接受。有相同问题的人可以使用它 :) - JohnP

3
你可能需要更改你的实现方式。等待这么长时间对于你应用程序的用户来说是一种烦恼,对于整个应用程序来说则是致命的。
对于这样的任务,通常最好将任务排队,最好在数据库上,并定期处理它们。Linux系统中有计划任务(chron jobs)。在Windows中,你可以使用调度程序来启动backgroundProcess.php。

1
这不是可以排队的事情。它是与远程服务器的ssh连接并处理一些东西。 - Emmanuel

2

除了Rohit上面的回答,我编辑了他的解决方案以适用于Windows 10 PHP 7.0.3:

pclose(popen("start /B ". $cmd, "w"));

1

在 Windows 环境中使用 exec() 命令时,重定向可能会指向 NUL:。而 /dev/null 是 *nix 系统的空文件。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接