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

通过AJAX调用终止服务器上的PHP脚本,php,javascript,ajax,apache,Php,Javascript,Ajax,Apache,我已经编写了一个PHP脚本来导入大量数据。导入过程通过Ajax调用触发,Ajax请求继续等待服务器响应。由于我在专用服务器上工作,因此没有超时问题 问题是我们需要一个可以终止导入过程的特性。例如,客户端上的停止按钮我们认为,如果我们终止了等待的ajax调用,那么服务器上的进程也将停止,因为没有服务请求。但不幸的是,事实并非如此,脚本继续在服务器端执行,而Ajax请求已经从客户端终止 其次,我们在这个项目中使用PHP会话。假设cancel按钮需要对服务器上的另一个脚本进行Ajax调用以停止进程,那

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

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

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


注意:根据我们的项目架构,我们要求每页都有会话_start()。如果有人能就这些问题提供指导,那就太好了。

在PHP脚本上设置一个略高于AJAX超时的时间限制怎么样?如果PHP脚本在一段时间内运行,那么它将停止运行。类似于此:

<?php

    set_time_limit(20);

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

?>


来源:

脚本运行后,只能通过结束对脚本的php进程来停止。一种可能是在调用另一个脚本时使用会话存储“continue”条件

例如:

脚本1是工作者(导入者)
脚本2是一个ajax反复调用的函数,只要导入程序可以工作。
脚本1和脚本2共享会话['lastPing']

所以

脚本2设置
$\u会话['lastPing']=time()

脚本1有一个条件:
if($_SESSION['lastPing']-30>time()){die();}

您可以在开始运行脚本时将进程ID写入文件、数据库或缓存。您可以使用获取进程ID。这假设每个脚本都有自己的进程ID


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

您可以使用。可能的步骤概要:

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

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

    所以,我强烈建议你找一个合适的工作经理,比如。gearman确实有一个问题。使用作业管理器可以让您完全控制每个流程。您可以启动/停止流程和TAK


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

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


    你没有问任何问题。@hobbs阅读了最后一行“如果有人能就这些问题提供指导,那就太好了”第二点:当脚本正在使用会话文件时,PHP会锁定该文件。除非您使用
    session\u write\u close()
    释放锁,否则在任何时候都只能使用一个使用PHP脚本的会话。由于应用程序使用PHP会话,并且第一个请求正在处理中,因此在第一个周期完成之前无法处理第二个请求。因此,如果我们进行另一个ajax调用,它将等待前面的请求完成。这是使用PHP会话的脚本的限制。PHP脚本应该没有超时,这就是我们使用VPS服务器的原因。只需给最终用户一个功能来终止他在服务器上启动的进程。您确定,当请求到达服务器时,它只创建一个进程吗?@asim ishaq我不理解您的问题。但正如我所说,这假设每个脚本都有自己的进程ID。如果我没有弄错的话,您还可以配置web服务器来处理同一进程中的所有请求。但我不认为这是最常用的选择。我经常遇到的是,web服务器在其自己的进程中运行(分叉)每个请求。实际上,我正在测试另一个想法。仍然不起作用。其思想是:用户取消ajax请求(完成)。服务器上的PHP脚本将继续检查连接是否中止,然后终止进程。我使用php函数connection_aborted()来确定连接的状态。如果终止,则返回1,否则返回0。问题是无论请求是否终止,它总是返回0。你知道吗?看@asim ishaq这是个好主意。有关连接状态的更多背景信息,请参阅。