PHP在运行过程中响应ajax

问题描述:

我试图从PHP运行一个长脚本时获取Ajax请求中的一些数据;PHP在运行过程中响应ajax

但是,当Ajax已经回答PHP中的脚本完成了,并且我需要在运行其他脚本时获得Ajax响应。

JS

setInterval(function(){ 
    $.post('progress.php','', 
    function(data){ 
     $('.-info-').html(data); 
    }); 
},100); 

progress.php

session_start(); 
echo $_SESSION['progress'].'%'; 

running.php

session_start(); 
$i=0; 
while($i<99){ 
    $i++; 
    $_SESSION['progress'] = $i; 
    //sleep(1); 
    //flush(); 
} 

有什么办法来respo那么当"while"正在运行?

+0

哇,哇,请参阅我的回答更新 – 2014-10-20 15:48:24

+0

写''__ SESSION'到磁盘不会发生,直到过程结束。会话文件无论如何都被锁定到*服务进程*,这意味着** progress.php **进程将挂起,直到** running.php **完成。您必须将进度写入您自己的文件并从** progress.php **中读取。 – 2014-10-20 15:49:00

编辑:Marc B是对的。会话将被锁定,不会根据需要进行更新。因此,您需要将进度存储在可以从多个连接异步访问的系统中 - 可能是数据库?

running.php:

session_start(); 
$i=0; 
while($i<99){ 
    $i++; 
    // Store progress in Database 
} 

progress.php:

session_start(); 
//read progress from Database 
+0

等等,onreadystatechange和状态3 – 2014-10-20 16:08:56

+0

我测试了所有的答案,所以我得到了存储到数据库中是容易和更好的.tanQ – talkhabi 2014-10-20 18:51:16

+0

我已经使用进度进行复制,通过在数据库中保存进度并通过Ajax读取它...工作正常**小文件**。但是当我选择一个文件(大约超过100MB)进行复制时,几秒钟后所有'Ajax's都无法运行,你能帮忙吗?对不起'我的坏英语 – talkhabi 2014-10-21 18:08:15

使用冲水()来发送输出到浏览器的onreadystatechange获得在客户端的响应

$i=0; 
while($i<99){ 
    $i++; 
    echo $i; 
    flush(); 
    sleep(1); 
} 

一个的onreadystatechange将在瓦塔的每一个部分,从您的脚本中调用(http://www.w3schools.com/ajax/ajax_xmlhttprequest_onreadystatechange.asp

你应该检查状态3 - 状态3 LOADING正在下载; responseText保存部分数据。所以你可以轻松地使用它 - 你可以在这里检查它developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

+0

你注意到他从jquery调用哪个脚本,哪一个锁定会话文件? – 2014-10-20 15:54:33

+0

当连接的*状态*改变时,'onreadystatechange'被触发 - *当页面内容改变时* not *。 – dognose 2014-10-20 15:57:00

+0

如果他将打印出当前状态 - 不需要使用会话 - 所以他可以关闭会话并独立处理数据 – 2014-10-20 15:57:24

PHP不会在每次更新时转储保存的会话数据的副本$_SESSION。当任何特定的进程正在使用它时,会话文件实际上被LOCKED。

你需要做的:

while($i<99){ 
    session_start(); // start session 
    $i++; 
    $_SESSION['progress'] = $i; 

    session_write_close(); // save session data, release session file lock 

    sleep(...); 
} 

换句话说,你的代码永远不会成功,因为你的running脚本将保持会话开启/锁定,防止progress从曾经访问它。

+0

这个工作,但是输出'($ _SESSION ['progress'])'是一个固定值吗? – talkhabi 2014-10-20 16:26:49

您可以使用全局变量,但考虑到更好的使静态或单例类

class counter { 
    private $_progress=0; 

    public static function doProgress() { 
    $i=0; 
    while($i<99){ 
    $i++; 
    $this->_progress = $i; 
    } 
    } 

    public static function getProgress() { 
    return $this->_progress; 
    } 

so in progress.php做

echo Counter::getProgress() 

,并在你的JavaScript,你必须使用setInterval()函数在我mermory在intervaled时候打电话的过程。php脚本

+0

'progress.php'我们没有'class Counter',如果我们再次定义它,它将会是一个新的'class'。不? – talkhabi 2014-10-20 17:23:49

+0

是的。这将是新的地址空间,新的过程。所以静态变量不会被共享 – 2014-10-20 19:04:58