我正在启动一个与PHP的asynchronous作业来执行一些testing。
为了使它工作,我find了一些提示,如使用popen
和start
:
$commande = "testu.bat"; $pid = popen('start /B ' . $commande, 'r'); $status = pclose($pid);
testu.bat
的文件夹在我的用户PATH中。
这个脚本执行一些任务,并控制它的执行,它应该生成一个日志文件,但我从来没有得到它。
而如果我只是删除/B
选项,它工作正常,我得到我的日志文件。
我错过了关于后台执行的东西吗? 如何在后台运行时捕获错误信息?
看来你是在假设/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
开关。
有趣的一个…好吧,这是我的想法:因为你在后台运行任务,PHP脚本将继续,它不会等待testu.bat返回任何东西…
或者换一种说法,popen按照指示要做的事情,即在后台启动任务,然后把控制权交还给PHP,而日志文件仍然在后台创建, PHP脚本进行同时…
在这种情况下,我会做的就是让testu.bat以一种回调类型的方式调用php脚本(或者另一个PHP脚本),一旦它完成了处理,就像在Javascript中使用类似于Ajax调用的回调函数一样。 ..
也许提供回调脚本命令作为参数testu.bat ..?
希望这有任何帮助…
我不太清楚你的目标,但是这里有一些你可能会用到的信息:
为了找出背景错误,你可能会发现这些功能是有用的:
set_exception_handler(); set_error_handler(); register_shutdown_function();
当然写出他们捕捉到的一些文件的错误。
如果您不需要从您的请求中获取任何数据,则可以简单地使用:
fsockopen() curl
并给他们一个短暂的超时(10毫秒)。 脚本将在后台运行。
或者,如果您确实需要返回数据,则可以将其放入数据库并设置一个循环来检查数据是否已被插入,或者只是将其输出到文件中并检查其是否存在。
在我看来, start
启动指定的命令,在“背景”创建一个新的prcoess。 因此, start
本身的执行“正好”开始第二个过程并立即存在。 但是,使用/B
开关,要执行的命令将在start
过程的上下文中执行。 因此start
过程的执行需要更长的时间。 现在我怀疑是执行pclose
终止start
过程,因此你不会得到你的日志文件。
也许一个解决方案(不是testet,虽然)可能会执行像start /B cmd "/C testu.bat"
,其中start
只是试图执行cmd
和cmd
获取/C testu.bat
作为参数,它是它应执行的“命令” 。
另一个想法:如果你不叫$status = pclose($pid);
会发生什么$status = pclose($pid);
?
您的问题很可能通过使用队列系统得到妥善解决。 将作业插入到后台进程拾取并处理的队列中。 通过这种方式,后台任务完全独立于启动任务的HTTP请求,但您仍然可以监视其进度。
两种最流行的软件包可以帮助你在你的场景中:
Gearman的
的RabbitMQ
请注意,实施排队解决方案不是一个5分钟的前景,但从技术上讲,这种情况是正确的。 对于公司产品来说,这是唯一可行的方法。 对于个人项目而言,只需要一些工作,就需要一定程度的承诺,才能第一次看到。 如果你想扩大你的发展视野,我强烈建议你排队。