2013-05-13 138 views
2

我已经编写了一个PHP脚本来导入大量的数据。导入过程通过Ajax调用触发,并且ajax请求继续等待服务器响应。由于我在专用服务器上工作,所以不存在超时问题。通过AJAX调用终止服务器上的PHP脚本

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

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

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

+0

你没有问一个问题。 – hobbs 2013-05-13 12:16:26

+0

@hobbs阅读最后一行“如果有人能够就这些问题提供指导,这将很好” – 2013-05-13 13:44:13

+2

第二点:当脚本主动使用它时,PHP锁定会话文件。除非'session_write_close()'释放锁定,否则任何时候都只能使用一个会话使用PHP脚本。 – 2013-05-13 14:02:56

回答

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

+0

PHP脚本应该没有超时,这就是为什么我们使用VPS服务器。只需给最终用户一个功能即可终止他在服务器上启动的进程。 – 2013-05-13 13:50:49

0

一旦脚本运行它只能通过结束PHP程序的脚本工作停止。当另一个脚本被调用时,一种可能性是使用会话来存储“继续”条件。

例如:

脚本1是工人(进口商)
脚本2是通过反复的AJAX调用只要进口商应的功函数。
脚本1和2分享我们说$_SESSION['lastPing']

所以

脚本2套$_SESSION['lastPing'] = time();上的每个呼叫。
脚本1有条件if($_SESSION['lastPing'] - 30 > time()){ die(); }

+0

由于应用程序使用PHP SESSION并且第一个请求正在处理中,所以第二个请求无法处理util第一个周期完成。所以如果我们做了另一个Ajax调用,它会等到先前的请求完成。这是使用PHP会话的脚本的限制。 – 2013-05-13 13:48:54

0

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

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

+0

您确定,当请求到达服务器时,它只创建一个进程? – 2013-05-13 14:15:18

+0

@ asim-ishaq我不明白你的问题。但正如我所说的,这假设每个脚本都有自己的进程ID。如果我没有弄错,你也可以配置你的web服务器来处理同一个进程中的所有请求。但我不认为这是最常用的选择。我经常遇到的情况是,Web服务器在自己的进程中运行(分叉)每个请求。 – 2013-05-13 14:17:56

+0

@ asim-ishaq想知道这是否工作...请告诉 – 2013-05-13 19:19:27

0

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

  1. 创建一个唯一标记并将其传递到服务器以及开始导入的顺序。
  2. 当接收到订单(通过AJAX)时:
    a)存储表明正在处理该令牌的记录(通过file,db,memcached)。
    b)使用proc_open运行导入脚本。
    c)开始轮询循环,检查来自(2a)的记录以查看该令牌仍处于处理状态。如果没有,请致电proc_terminate并退出循环。
  3. 如果给定的顺序停止进口(在一个单独的AJAX调用),更新持久记录表明,特定的标记应停止,这将有所回升(2C)
1

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

所以,我强烈建议使用合适的工作经理,如gearman。 gearman确实有一个php extensions。使用工作经理将使您完全控制每个过程。你可以开始/停止进程& taks。

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

相关问题