我在一些控制器中有一个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会话-这肯定会发生)