此网页触发的网页和php脚本之间的通信


Communication between web page and php script triggered from this web page

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

public function myAction() {
    ...
    $myAnalyzer = new Analysis();
    $myAnalyzer->analyze();
    ...
}

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

function analyze() {
... 
    foreach($items as $rv) {
        ...
        ...
        // new result should be stored in db here 
    }
}

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

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

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

第二个问题:如何知道每个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。

我很感激事先的帮助。

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

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

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将调用parrent窗口中的某个函数,该函数将更新您的页面。如果您想获得更多信息,这是长轮询COMET实现之一。有一些陷阱(例如,你可能需要确保你发送了一些特定数量的符号作为响应,以便在某些浏览器中执行它),但仍然可以使用(一些网络浏览器聊天就是基于此)。

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

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