2013-06-19 53 views
0

我有一個很長的工作來填補數據庫中的表。這項工作可能需要不同的時間才能完成。 所以,我需要一個進度條。只需指向頁面就足夠了。 迄今爲止,我發現了幾種解決方案:在腳本之間實現共享變量或如何實現服務器端進度的正確方法?

  1. 使用_SESSION。好的,它適用於我使用的大多數服務器,但是我在chrome上有很多ERR_RESPONSE_HEADERS_TOO_BIG錯誤,有時 - 在某些服務器上,由於在循環中調用session_start/session_write_close而導致「頭已發送」。我喜歡這種方法,但現在我已經拒絕
  2. 使用一種ob_start/ob_end_flush的長期運行的循環內。這不起作用。它只是在腳本結束後顯示所有緩衝的echo-ed消息。
  3. 使用分貝爲存儲共享變量(沒試過還)
  4. 使用單獨的(臨時)文件。 (尚未嘗試)。

我已經實現了基礎架構:一個用於長時間工作的腳本(在db中填充一個表),另一個用於JS讀取包含進度狀態的共享變量。我用jQuery .ajax方法調用的這兩個腳本都期望得到.done函數的結果。

有沒有其他的方法呢?看起來我會喜歡使用4)變體,但我想知道實施進度條的慣例是什麼。

謝謝:)

+1

其建議您運行使用某種類型的後臺任務管理器的這些長期工作。我強烈建議你不要使用瀏覽器會話來運行它們。您可以讓瀏覽器請求它運行,但實際運行應排隊並在後臺執行。 – DevZer0

+0

您是否試過這個解決方案 - http://spidgorny.blogspot.com/2012/02/progress-bar-for-lengthy-php-process。html? –

+0

@ DevZer0 - 後臺作業管理器看起來很有趣。任何簡單的例子? – netanalyzer

回答

0

首先,如果你還沒有,我會運行PHP代碼作爲一個單獨的過程。

<?php 

exec('/usr/bin/php /Path/to/script.php {$param1} {$param2} > /dev/null 2>/dev/null &'); 

?> 

然後我會得到這個過程中更新數據庫,其針對用戶的ID進度,然後你可以使用超時函數內部調用Ajax獲取狀態(許多DB如何寫完整,怎麼許多離開,等等)從數據庫。

0

那麼使用會話的路要走,但如果什麼用戶不小心關閉瀏覽器嗎?然後進度條將重置爲其初始狀態。此外,你得到的錯誤是因爲你呼應 HTML 被髮送之前。

所以去的最好方式在我看來是存儲在一個表(數據庫)的進展,每次用戶訪問一個頁面將其拉出表並顯示它是如何工作的很多%已經完成。

步驟:

1. Default State In Table: 0 - indicates that user has not filled out anything 
2. User Fills out page 1 update progress in table: 1 - indicates user completed page 1 
3. User Fills out page 2 update progress in table: 2 - indicates user completed page 2 

顯示這個百分比就如下:

$total = 3; //total pages that user needs to fill out 
$filledOut = $db->getUserProgressStatus(); //return the digit status of user progress 
$percent = ($filledOut/$total) * 100; //gives you % value 

所以這就是你得到的值在每一頁上:

Page 1: (0/3) * 100 = 0% 
Page 2: (1/3) * 100 = 33% //first page completed 
Page 3: (2/3) * 100 = 67% //second page completed 
Page 4 (summary page): (3/3) * 100 = 100% //completed 
+0

我很滿意這個答案。測試是必須的:) – netanalyzer

0
function fcflush() 
{ 
    static $output_handler = null; 
    if ($output_handler === null) { 
     $output_handler = @ini_get('output_handler'); 
    } 
    if ($output_handler == 'ob_gzhandler') { 
     // forcing a flush with this is very bad 
     return; 
    } 
    flush(); 
    if (function_exists('ob_flush') AND function_exists('ob_get_length') AND ob_get_length() !== false) { 
     @ob_flush(); 
    } else if (function_exists('ob_end_flush') AND function_exists('ob_start') AND function_exists('ob_get_length') AND ob_get_length() !== FALSE) { 
     @ob_end_flush(); 
     @ob_start(); 
    } 
} 

//infinite loop example of usage 
$counter = 0; 
while (true) { 
    echo $counter."<br />"; 
    fcflush(); 
    $counter++; 
} 
+0

你如何停止循環? – GGio

+0

停止/重新啓動web服務器它的一個例子:)在實際中不使用它,你會做'while($ counter <100){'或其他一些條件 – Dave

相關問題