在php中为长时间运行的进程创建后台进程
好吧,如果这是另一个问题的重复,请原谅我,但在搜索之后,我没有找到一个明确的答案。我基本上想做的是让我的php web应用程序触发一些事件(如电子邮件发送程序或报表生成器),这些事件可能需要几分钟才能完成,并立即将控制权返回到页面。我来自一个.NET世界,在这个世界上,只需一个线程就可以轻松完成 以下是工作流程:在php中为长时间运行的进程创建后台进程,php,ajax,yii,background-process,Php,Ajax,Yii,Background Process,好吧,如果这是另一个问题的重复,请原谅我,但在搜索之后,我没有找到一个明确的答案。我基本上想做的是让我的php web应用程序触发一些事件(如电子邮件发送程序或报表生成器),这些事件可能需要几分钟才能完成,并立即将控制权返回到页面。我来自一个.NET世界,在这个世界上,只需一个线程就可以轻松完成 以下是工作流程: 用户单击“生成报告”按钮 ajax调用“../blah/generate report”并立即返回 流程启动并运行,直到完成,而用户可以继续他的业务 用户可以返回报告页面并查看进度:“
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://www.yoursite.com/background-script.php');
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_TIMEOUT_MS, 1);
curl_exec($ch);
curl_close($ch);
这将运行脚本,并立即返回页面。当然没有回调,所以最好将background-script.php的输出放入数据库,然后每隔一段时间从客户端ping数据库,直到看到结果。据我所知,shell\u exec或exec将阻止php脚本的执行,直到进程终止。 一种解决方案是在命令末尾附加一个“&”,脚本/程序将被后台处理
"/usr/report.sh &"
我曾使用类似的方法从PHP运行外部工具,但通过一个中间脚本来控制PID、实例数。。。
无法确定它是否在Windows主机下工作。我们在这里创建了一个函数,该函数将向浏览器返回答案并继续执行。我们使用它发送电子邮件,而不必让用户等待
public function redirectAndContinue( $url )
{
ignore_user_abort(true);
header("Location: $url");
header("Connection: close");
header("Content-Length: 0");
flush();
}
你可以这样使用它
// do quick basic stuff to validate your report
$this->redirectAndContinue( $url )
// send your email or do other slow stuff
问题是:它不适用于AJAX,它必须是一个常规页面请求(可能是一篇文章)。但是你还是可以制作进度条:在数据库或会话中保存一些内容,然后继续调用一些URL,通过AJAX获取进度。我可以推荐Gearman吗?您可以向gearman服务器提交作业并请求状态 Gearman为使用多台机器或进程提供了分布式应用程序框架。它允许应用程序并行完成任务、负载平衡处理以及在不同语言之间调用函数。该框架可用于各种应用程序。Gearman是多线程的,已知每秒能够执行5万个作业 这里有一个快速教程:
这也很容易入门,所有代码都将使用PHP。PHP是单线程的。如果您有进程控制扩展,您可以生成额外的PHP进程,但它们不是线程。或者,您可以
exec('/usr/bin/php name_of_script.php')
为了更正上述注释,存在向开发人员公开线程功能的pthreads扩展。但是,即使这样,您仍然无法提供HTML和执行后台任务,因为web服务器进程将一直挂起,直到PHP进程完成,并且只有在所有线程完成后才会完成。您需要的是实现作业服务器或任务场。我想起了Gearman,他可能会有所帮助。使用web请求填充不同进程的队列。然后执行另一个HTTP请求来查询作业状态。另一个注释来更正我自己的:)如果您对任何使用线程的机会感兴趣,您可以查看我将链接的存储库,它向您展示如何执行异步请求,如果这解决了您的问题(尽管Drew的回答提供了以较少的麻烦处理该任务的方法).@N.B.我知道pthreads,但它不是一个常用的扩展,并且有某些要求,这可能会导致安装问题。这只是转发原始请求,也就是说,它不会使其异步。例如:如果background-script.php在1分钟内没有重新响应,则在同一会话中发送的任何异步请求都将等到Background脚本将发送其响应。其中的异步是什么?