【问题标题】:Communication between web page and php script triggered from this web page网页与从该网页触发的 php 脚本之间的通信
【发布时间】:2012-09-02 20:48:14
【问题描述】:

我在某些控制器中有一个 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 会使用这个 process-id 停止 myAnalyzer。

提前感谢您的帮助。

【问题讨论】:

标签: php ajax zend-framework communication webpage


【解决方案1】:

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

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

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

第三问:看看this 页面。您可以将其设置为 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 会话——这肯定会发生)

【讨论】:

  • 非常感谢您的回答。但是反向通信呢?我的意思是从worker.php 到my.phtml? my.phtml 的某些部分必须重新渲染(可能通过另一个 ajax)。最好的情况是在每个 foreach 循环之后。这是我的第二个问题。
  • 再次感谢!在深入探讨您的答案之前,我想知道在 zend 框架级别上是否还有另一种解决方案。在这种情况下,my.phtml 调用 workerAction 而不是 worker.php。希望有某种可能性....
  • 我认为没有什么能阻止您像任何常规 Zend 操作那样调用 workerAction。但是用一些神奇的zend函数制作单独的“线程” - 我不这么认为。请记住,zend 正在缓存输出,如果您想发送部分数据作为响应 - 它可能会导致问题。
猜你喜欢
  • 2011-02-16
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多