我目前正在使用PHP启动异步作业来执行一些测试。
为了使其有效,我在SO上找到了一些提示,例如使用popen
和start
:
$commande = "testu.bat";
$pid = popen('start /B ' . $commande, 'r');
$status = pclose($pid);
testu.bat
的文件夹位于我的用户路径中。
这个脚本执行一些任务,为了控制它的执行,它应该生成一个日志文件,但我从来没有得到它。
然而,如果我只删除/B
选项,它可以正常工作,我会得到我的日志文件。
我是否错过了有关后台执行的内容?如何在后台运行时捕获错误信息?
答案 0 :(得分:4)
看来你的运作是假设/B
切换到start
命令意味着"背景"。它不是。来自start
用法:
B Start application without creating a new window. The
application has ^C handling ignored. Unless the application
enables ^C processing, ^Break is the only way to interrupt
the application.
start
启动的进程默认是异步的。由于这似乎是您想要的,只需运行没有/B
开关的命令。
答案 1 :(得分:1)
有趣的人......好的,这就是我的想法: 因为您在后台运行任务,所以PHP脚本将继续运行,它不会等待testu.bat返回任何内容......
或者换句话说,popen完成了它所要做的事情,它在后台开始执行任务(它确实如此)但是然后控制立即返回到PHP,而日志文件仍然在背景和php脚本同时进行...
在这种情况下,我要做的是让testu.bat在完成处理后以回调类型方式调用php脚本(或其他PHP脚本),方式与在Javascript中使用回调类型的异步方式相同Ajax调用......
也许将callback脚本命令作为参数提供给testu.bat ..?
希望这有任何帮助......
答案 2 :(得分:1)
我不太确定你的目标,但这里有一些你可能会使用的信息:
要找出背景错误,您可能会发现这些函数很有用:
set_exception_handler();
set_error_handler();
register_shutdown_function();
当然要将他们捕获的错误写出来。
如果您的请求中不需要任何数据,您只需使用:
fsockopen()
curl
并给他们一个短暂的超时(10 milisec)。脚本将在后台运行。
或者,如果您确实需要数据,您可以将其放入数据库并设置一个循环来检查数据是否已经插入,或者只是将其输出到文件中并检查其存在。
答案 3 :(得分:1)
在我看来,start
通过在" background"中创建一个新的prcoess来启动指定的命令。因此,执行start
本身"只是"启动第二个过程并立即存在。
但是,使用/B
开关,将在start
进程的上下文中执行要执行的命令。因此,start
进程的执行需要更长时间。现在我怀疑执行pclose
会终止start
进程,因此您无法获取日志文件。
也许一个解决方案(不是testet)可以执行类似的东西
start /B cmd "/C testu.bat"
其中start
只是尝试执行cmd
而cmd
获取/C testu.bat
作为参数,即"命令"它应该执行。
另一个想法:
如果您不打电话给$status = pclose($pid);
会怎样?
答案 4 :(得分:0)
对于某些寻求此技巧的人来说,就我而言,它只需要激活php.ini中的PHP指令 ignore_user_abort 或通过PHP平台功能激活即可。
如果未激活此选项,则pclose()会终止该进程,而不会完成工作。