1

我在某些控制器中有一个 myAction 函数。它有一个类实例:

public function myAction() {

    ...
    $myAnalyzer = new Analysis();
    $myAnalyzer->analyze();
    ...
}

假设这个函数analyze() 需要10 分钟。这意味着它会阻止 my.phtml 10 分钟,这是不可接受的。我想要的是首先呈现 my.phtml,然后在 my.phtml 上显示来自 analyze() 的中间结果。

function analyze() {

... 
    foreach($items as $rv) {

        ...
        ...
        // new result should be stored in db here 
    }

}

据我所知,这是不可能的,因为 PHP 中只有一个线程。所以我决定从 my.phtml ajax-call 来运行 myAnalyzer 实例。

第一个问题:对吗?我可以在 myAction() 中进行而不阻塞吗?

好的,现在我在 javascript 或 JQuery 的帮助下使用 my.phtml 中的一些脚本(比如 worker.php)运行 myAnalyzer。

第二个问题:我怎么知道每个 foreach 循环何时结束?换句话说,我怎样才能让 worker.php 向 my.phtml 或 zend 框架发送一些信号(或事件)。我不想使用 javascript 计时器按时间更新 my.phtml。这就是我需要知道的全部内容,因为中间数据应该存储在 DB 中。

第三个问题:当用户离开页面时,myAnalyzer 必须停止。为此,我有这个代码。

window.onbeforeunload = function(e) {

    // killer.php kills myAnalyzer
};

但是 javascript 如何与 myAnalyzer 通信呢?有类似进程ID的东西吗?我的意思是,当worker.php 运行myAnalyzer 时,它会在zend 框架中注册它的进程ID。当用户离开页面时,killer.php 使用这个进程 ID 停止 myAnalyzer。

我提前感谢您的帮助。

4

1 回答 1

1

第一问:是的,恐怕这是正确的。

第二个问题:我不明白你在这里的意思。请参阅下面的代码示例

foreach($data => $item) {
   ...
}
//code here will be executed only after foreach loop is done. 

第三问:看看这个页面。您可以将其设置为 false(但我想它已经是那样了)并不时向客户发送一些东西。或者您可以将其设置为 true 并检查用户是否仍与connection_aborted功能连接。我的意思是,您可以使用 ajax 运行您的 worker.php 并配置您的请求,这样浏览器就不会因为超时而断开连接(因此在用户停留在页面时将保持连接)。但是如果用户离开页面,它将被关闭。

编辑: 关于第二个问题。有几个选项:

1)您可以使用一些共享内存(例如 memcached)。并且不时用另一个ajax请求调用服务器。因此,在每个循环结束后 - 您将一些值放入 memcached 并在请求期间您可以检查该值并根据该值构建响应/更新您的页面

2)有像部分反应这样的事情。可以使用 XMLHTTPRequest 获得一些响应,但我记得 - 目前这并不是真正有用,因为许多浏览器不支持它。我没有这方面的任何细节。从未尝试过使用它,但我确信某些浏览器允许使用 XMLHTTPRequest 处理部分响应。

3) 您可以使用不可见的 iframe 来调用您的 worker.php 而不是 XMLHTTPRequest。在这种情况下,您可以发送一些可以放置 javascript 的内容,该 javascript 将在父窗口中调用某个函数,该函数将更新您的页面。如果您想获得更多信息,那是长轮询COMET实现之一。有一些陷阱(例如,您可能需要确保发送一些特定数量的符号作为响应,以便在某些浏览器中执行),但仍然可以使用(某些网络浏览器聊天基于这个)。

2)和3)也很好,因为它会自动解决你的第三个问题。同时 1) 可能更简单,但它不会解决第三个问题的问题。

还有一件事 - 因为您将有长时间运行的脚本,您必须记住会话可能会阻止任何其他请求的执行(如果使用基于默认文件的 PHP 会话 - 这肯定会发生)

于 2012-09-03T05:10:15.950 回答