繁体   English   中英

通过AJAX调用在服务器上终止PHP脚本

[英]Terminate PHP script on server through AJAX call

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

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

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

注意:根据我们的项目架构,我们需要在每个页面上使用session_start()。 如果有人能指导这些问题,那将是一件好事。

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

因此,我强烈建议使用像齿轮工这样的合适的工作经理。 gearman确实有一个PHP扩展 使用作业管理器可以让您完全控制每个过程。 你可以开始/停止进程和taks。

另一个选择是使用队列(如amqp )来更清晰地处理这些任务。 哪一个更适合您的用例,我会让您决定。

如何在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

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

例如:

脚本1是工人(进口商)
脚本2是ajax重复调用的函数,只要导入器可以工作。
脚本1和2共享让我们说$_SESSION['lastPing']

所以

脚本2设置$_SESSION['lastPing'] = time(); 每次通话。
脚本1有一个条件if($_SESSION['lastPing'] - 30 > time()){ die(); } if($_SESSION['lastPing'] - 30 > time()){ die(); }

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

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

您可以使用proc_函数来处理此问题。 可能的步骤概述:

  1. 创建一个唯一的令牌并将其与订单一起传递给服务器以开始导入。
  2. 收到订单时(通过AJAX):
    a)存储显示正在处理此令牌的记录(通过文件,db,memcached)。
    b)使用proc_open运行导入脚本。
    c)开始轮询循环,检查(2a)中的记录以查看该令牌仍处于处理状态。 如果没有,请调用proc_terminate并退出循环。
  3. 如果给出了停止导入的命令(在单独的AJAX调用中),请更新持久记录以指示应该停止特定令牌,这将在(2c)中被选中

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM