2014-10-20 114 views
0

我試圖從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

回答

1

編輯: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

1

使用沖水()來發送輸出到瀏覽器的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

1

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

0

您可以使用全局變量,但考慮到更好的使靜態或單例類

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