在php中为长时间运行的进程创建后台进程

时间:2014-02-06 14:26:55

标签: php ajax yii background-process

好的,请原谅我,如果这是另一个问题的重复,但在搜索后我没有找到一个明确的答案。我基本上想要做的是让我的php web应用程序触发一些事件(如电子邮件或报告生成器)可能需要几分钟才能完成并立即将控制权返回给页面。我来自.NET世界,可以通过线程轻松完成。

所以这是工作流程:

  1. 用户点击“生成报告”按钮
  2. ajax致电'../blah/generate-report'并立即返回
  3. 流程启动并运行直至完成,然后用户可以开展业务
  4. 用户可以返回报告页面并查看进度:“报告50%完成”
  5. 实现这一目标的最佳方法是什么?简短的回答很好。我不想为我编写代码,只是一些指导。我查看了shell_exec,但我不确定这是否是最佳方式,或者是否,如何使用它来处理Web应用程序中的功能。 (如果这有任何区别,我正在使用Yii框架)。感谢。

    -Jason

4 个答案:

答案 0 :(得分:2)

在PHP中启动新的线程线程的最佳(也是唯一的AFAIK)方法是使用curl之类的东西创建一个新的PHP请求。

$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数据库,直到看到结果为止。

答案 1 :(得分:2)

我们在这里创建了一个函数,它返回浏览器的答案并继续执行。我们使用它发送电子邮件而不让用户等待它。

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,它必须是常规页面请求(可能带有POST)。但是你仍然可以创建进度条:在数据库或会话中保存一些东西,然后继续调用一些URL来通过AJAX获得进度。

答案 2 :(得分:1)

据我记忆,shell_exec或exec将阻止PHP脚本的执行,直到进程终止。 解决方案是添加“&”在命令结束时,您的脚本/程序将被后台化。

"/usr/report.sh &"

我使用类似的东西从PHP运行外部工具,但通过中间脚本来控制PID,实例数... 不能说它是否在Windows主机下运行。

答案 3 :(得分:0)

我可以建议Gearman吗?您可以将作业提交给齿轮箱服务器并请求状态。

Gearman提供了一个分布式应用程序框架,用于处理多台机器或进程。它允许应用程序并行完成任务,负载平衡处理和语言之间的函数调用。该框架可用于各种应用程序。 Gearman是多线程的,已知能够每秒执行5万个工作。

快速教程在这里:http://www.sitepoint.com/introduction-gearman-multi-tasking-php/

它也很容易上手,所有代码都将使用PHP。