4

我编写了一个 PHP 脚本来导入大量数据。导入过程通过 Ajax 调用触发,ajax 请求继续等待服务器响应。因为我在专用服务器上工作,所以没有超时问题。

问题是我们需要一个可以终止导入过程的功能。例如客户端的停止按钮。我们认为如果我们终止了等待的 ajax 调用,那么服务器上的进程也会停止,因为没有请求服务。但不幸的是,情况并非如此,脚本继续在服务器端执行,而 Ajax 请求已经被客户端杀死。

其次,我们在这个项目中使用 PHP 会话。假设如果取消按钮需要对服务器上的另一个脚本进行 Ajax 调用以停止进程,那么如果已经有等待的 ajax 请求,该请求将如何到达服务器。Php/Apache 将保留第二个请求,直到第一个请求周期完成。

注意:根据我们的项目架构,我们需要在每个页面上都有 session_start()。如果有人能指导这些问题,那就太好了。

4

6 回答 6

1

您可以在开始运行脚本时将进程 ID 写入文件、数据库或缓存。您可以通过http://php.net/manual/en/function.getmypid.php获取进程 ID 。这假设每个脚本都有自己的进程 ID。

终止脚本(不使用锁定的会话)可以读取该进程 ID 并尝试终止它。

于 2013-05-13T14:13:18.870 回答
1

在 PHP 中执行长时间运行的进程时要小心,因为 PHP 的 zend 引擎和 GC 不适合长时间运行的进程。

所以,我强烈建议使用像gearman这样合适的工作管理器。gearman 确实有一个php 扩展。使用作业管理器可以让您完全控制每个流程。您可以启动/停止进程和任务。

另一种选择是使用队列,如amqp,更干净地处理这些任务。哪一个更适合你的用例,我让你决定。

于 2013-05-13T17:48:06.777 回答
0

如何在 PHP 脚本上设置一个略高于 AJAX 超时的时间限制?如果 PHP 脚本随着时间的推移运行,这应该会杀死它。与此类似的东西:

<?php

    set_time_limit(20);

    while ($i<=10)
    {
        echo "i=$i ";
        sleep(100);
        $i++;
    }

?>

来源: http: //php.net/manual/en/function.set-time-limit.php

于 2013-05-13T12:15:56.660 回答
0

一旦脚本运行,它只能通过结束处理脚本的 php 进程来停止。一种可能性是在调用另一个脚本时使用会话来存储“继续”条件。

例如:

脚本 1 是工作程序(导入程序)
脚本 2 是一个由 ajax 重复调用的函数,只要导入程序可以工作。
假设脚本 1 和 2 共享$_SESSION['lastPing']

所以

每次调用脚本 2 组$_SESSION['lastPing'] = time();
脚本 1 有一个条件if($_SESSION['lastPing'] - 30 > time()){ die(); }

于 2013-05-13T12:25:22.900 回答
0

您也许可以使用proc_函数来处理这个问题。可能的步骤大纲:

  1. 创建一个唯一令牌并将其与开始导入的订单一起传递给服务器。
  2. 当接收到导入命令时(通过 AJAX):
    a) 存储一条记录,表明该令牌正在被处理(通过文件、数据库、内存缓存)。
    b) 使用 运行导入脚本proc_open
    c) 开始轮询循环,检查 (2a) 中的记录以查看此令牌仍处于处理状态。如果没有,调用proc_terminate并退出循环。
  3. 如果给出了停止导入的命令(在单独的 AJAX 调用中),则更新持久记录以指示应停止特定令牌,这将在 (2c) 中提取
于 2013-05-13T17:47:09.423 回答
0

转到以下链接以获取问题的确切解决方案:

如果 HTTP 请求被取消/关闭,PHP 会自动终止脚本

于 2013-05-16T19:08:21.060 回答