简体   繁体   English

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

[英]creating background processes in php for long running process

Ok so forgive me if this is a repeat of another question, but after searching I have not found a clear answer. 好的,请原谅我,如果这是另一个问题的重复,但在搜索后我还没有找到一个明确的答案。 What I basically want to do is have my php web application fire off some event (like an emailer or report generator) that may take a few minutes to complete and immediately return control to the page. 我基本上想要做的是让我的php web应用程序触发一些事件(如电子邮件或报告生成器)可能需要几分钟才能完成并立即将控制权返回给页面。 I come from a .NET world where this can easily be accomplished with a thread. 我来自.NET世界,可以通过线程轻松完成。

So here's the workflow: 所以这是工作流程:

  1. User clicks 'generate Report' button 用户点击“生成报告”按钮
  2. ajax call made to '../blah/generate-report' and returns immediately ajax调用'../blah/generate-report'并立即返回
  3. process is started and runs until completion while the user can then go about his business 进程启动并运行直到完成,然后用户可以开始他的业务
  4. User can return to report page and see progress: "Report 50% complete" 用户可以返回报告页面并查看进度:“报告50%完成”

What's the best way to accomplish this? 实现这一目标的最佳方法是什么? Brief answers are fine. 简短的回答很好。 I don't want code written for me, just some guidance. 我不想为我编写代码,只是一些指导。 I looked at shell_exec but I'm not sure exactly if that is the best way or if it is, how to use it to process functions within a web app. 我查看了shell_exec,但我不确定这是否是最佳方式,或者是否,如何使用它来处理Web应用程序中的功能。 (I'm using the Yii framework if that makes any difference). (如果这有任何区别,我正在使用Yii框架)。 Thanks. 谢谢。

-Jason -Jason

The best (and only AFAIK) way to start a new thread thread like thing in PHP is to create a new PHP request using something like curl. 在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);

This will run the script, and immediately return the page. 这将运行脚本,并立即返回页面。 Of course there's no callback, so your best bet is to put the output of background-script.php into a database, and then ping the database every so often from the client until you see the results. 当然没有回调,所以最好的办法是将background-script.php的输出放入数据库,然后每隔一段时间从客户端ping数据库,直到看到结果为止。

We've created a function here that returns an answer to the browser and keeps executing. 我们在这里创建了一个函数,它返回浏览器的答案并继续执行。 We use it to send email without making the user wait for it. 我们使用它发送电子邮件而不让用户等待它。

public function redirectAndContinue( $url )
{
    ignore_user_abort(true);
    header("Location: $url");
    header("Connection: close");
    header("Content-Length: 0");
    flush();
}

You may use it like this 你可以像这样使用它

// do quick basic stuff to validate your report

$this->redirectAndContinue( $url )

// send your email or do other slow stuff

The problem is: it doesn't work with AJAX, it must be a regular page request (possibly with a POST). 问题是:它不能与AJAX一起使用,它必须是常规页面请求(可能带有POST)。 But you can make the progress bar anyway: save something in your database or session and then keep calling some URL to get the progress via AJAX. 但是你仍然可以创建进度条:在数据库或会话中保存一些东西,然后继续调用一些URL来通过AJAX获得进度。

As far as I remember, shell_exec or exec will block the execution of your PHP script until the process will terminate. 据我所知,shell_exec或exec将阻止PHP脚本的执行,直到进程终止。 A solution is to append a "&" at the end of your command, your script/program will be backgrounded. 解决方案是在命令末尾添加“&”,您的脚本/程序将被后台化。

"/usr/report.sh &"

I have used something like that to run external tool from PHP, but passing by an intermediary script to control PID, number of instances... Can't say if it is working under Windows host. 我曾经使用类似的东西从PHP运行外部工具,但通过中间脚本来控制PID,实例数量......不能说它是否在Windows主机下工作。

May I suggest Gearman? 我可以建议Gearman吗? You can submit jobs to a gearman server and request the status. 您可以将作业提交给齿轮箱服务器并请求状态。

Gearman provides a distributed application framework for work with multiple machines or processes. Gearman提供了一个分布式应用程序框架,用于处理多台机器或进程。 It allows applications to complete tasks in parallel, to load balance processing and to call functions between languages. 它允许应用程序并行完成任务,负载平衡处理和语言之间的函数调用。 The framework can be used in a variety of applications. 该框架可用于各种应用程序。 Gearman is multi-threaded and is known to be able to carry out 50 thousand jobs per-second. Gearman是多线程的,并且已知能够每秒执行5万个作业。

A quick tutorial is here: http://www.sitepoint.com/introduction-gearman-multi-tasking-php/ 这里有一个快速教程: http//www.sitepoint.com/introduction-gearman-multi-tasking-php/

Its also quite easy to get started, and all your code will be in PHP. 它也很容易上手,所有代码都将使用PHP。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM