在发送响应之前立即发送到后台操作

Send to background action right before response is sent

我读了很多书,但我尝试过的一切都没有奏效。 我将尝试简要解释我的问题,让我们看看是否有解决方案。 我正在使用使用 Yii 开发的网络应用程序。

过程是:

- Someone send a form to our web.
- Save user info in our DB
- Send that info to another web.
- Build a log and send it to admin
- 'OK' is sent to the user.

所有这个过程大约需要 20 seg。用户离开页面的时间过长。 所以问题是我需要用户在他的信息被保存后立即收到 'OK'。像这样:

- Someone send a form to our web.
- Save user info in our DB.
- 'OK' is sent to the user.
- Send that info to another web.
- Build a log and send it to admin.

我需要使进程异步,以便在发送响应后,进程在后台保持 运行ning。

我在模型中有 3 个方法: - 方法 1 -> 保存用户信息。 - 方法 2 -> 发送信息。 - 方法 3 -> 构建并发送报告。

在控制器中,我有一个由发送表单的网络调用的方法,它会触发所有进程并最终将 'OK' 发送到网络。

是这样的:

public function actionAux(){
    $form = new Form();
    $form->method1;
    $form->method2;
    $form->method3;

    $this->response(); // This send the 'OK'
}

好吧,我需要这些方法按顺序触发,但 2 和 3 运行 在后台,以便在保存用户信息后立即发送响应(方法 1)。

希望我已经解释清楚了,我可以找到解决方案。 提前致谢。

你不能打破任何线性过程。但是为了支持您的需求类型,您需要像 (ZeroMQ, BeanstalkD, GearMan 等...).

这样的排队工具

这些类型的工具非常轻便、多螺纹且耐用性极佳。在我当前的项目中,我正在使用 BeanstalkD。我们曾要求向 10,000 个用户发送消息,但不希望发件人等到。

  1. ZeroMQ support for php
  2. Yii (php) 扩展也可用于 beanstalk
  3. GearMan for php

祝一切顺利!!

PHP 本身提供的解决此问题的一种方法是使用 flush()ob_flush()

这意味着完全按照您的要求执行:将输出发送到代理(浏览器)并继续执行之后的任何 PHP。

不幸的是,这是否有效取决于很多因素,阅读 here

如果所有条件都满足此机制按预期工作,您可以这样做:

$form = new Form();
$form->method1();
$this->response();

ob_flush();
flush();

$form->method2();
$form->method3();

但是,根据上述因素,这可能不像上面的示例那么简单。 Here 是一本关于如何使用 PHP 作为 CGI 和 Apache 网络服务器确保将内容发送到浏览器的好读物。

如果这种方法在您的特定情况下变得不可能,还有另一种涉及后台执行的方法,我不会在这里详细说明,但它会像这样:

0) 编写一个 PHP 脚本,能够以所需方式在 CLI 模式下处理数据 1)执行方法1 2)在后台执行脚本,例如exec('/usr/bin/php yourscript.php?userData1='. $someData . '&userData2=' . $otherVar . ' &')(注意命令末尾的 &;这会将进程发送到后台,因此 exec() returns 立即。) 3) 发送响应。