2015-05-16 12 views
0

我的data目錄中有8000個html文件。我通過遍歷目標目錄解析所有html文件並調用解析函數。文件名將在何時被解析我的程序。立即顯示一個冗長的PHP腳本的中間結果

<?php 
base_dir="c:\data"; 
function parse($fname){ 
//to parse data from the file,omitted codes 
    echo $fname; 
    } 

foreach(new RecursiveDirectoryIterator(base_dir) as $item){ 
    parse($item); 
    } 
?> 

我發現,文件名會顯示在網頁上,直到被執行了我的整個PHP文件,文件名會顯示在10分鐘內,當一個文件被削減了沒有一個顯示的文件名之一。 如何在網頁上即時顯示結果,而不是等到整個php文件完成?
對於我來說,顯示文件名是很重要的,我知道如果我的代碼存在問題,如果很長時間過去了,網頁上沒有任何顯示會讓我感到緊張。

+0

使用[AJAX](http://www.w3schools.com/ajax/):) – someOne

+0

你試圖做的事情 - 不是很清楚。請在你的問題中提供更多細節。 – JoelParke

+1

你會發現[這篇文章](http://www.sitepoint.com/php-streaming-output-buffering-explained/)回答你的問題,解釋刷新輸出緩衝區和一個AJAX示例。 – initall

回答

0

1. PLAIN

最簡單的方法是禁用任何輸出緩衝,並且使用flush好措施。另外,禁用壓縮。

<?php 
    while (ob_get_level()) { 
     ob_end_clean(); // or ob_end_flush() if you want to display previous output from this script. 
    } 

    ... 
    print "Whatever\n"; 
    flush(); 

上述允許最小修改到您當前密碼。它幾乎沒有保證,因爲解析過程和瀏覽器之間的實際工作流可能包含很少或沒有控制權的實體(代理等);如果你執行外部程序,那些可能完全緩衝而不是行緩衝;等等。

2. AJAX

更復雜(但令人滿意的)的方法是,如果可能的話,分成兩個區塊這一點。這也構成了需要解決的安全風險。

在主要的PHP文件中,您輸出一個Javascript變量(在Javascript塊中)。

print "var filesToProcess = [\n"; 

print implode(",", array_map(
    function($rawFileName) { 
     return '"' . /*javascriptQuote*/($rawFileName) . '"'; 
    }, 
    $filesToProcess 
)); 
print "];\n"; 

這將提供給客戶端Javascript與所有文件的數組。

你現在可以做的處理AJAX:

function processOneFile() { 
    if (!window.filesToProcess.length) { 
     return; 
    } 
    // jQuery 
    $.post('/path/to/processor.php', 
     { file: window.filesToProcess.pop() }, 
     function(result) { 
      // ... see below 
     } 
    ).always(function(){ 
     window.setTimeout('processOneFile', 100); 
    }); 
} 

window.setTimeout('processOneFile', 100); 

這將調用PHP文件,一個文件中的其他後處理。結果必須在JSON返回:

Header("Content-Type: application/json;charset=UTF-8"); 
die(json_encode(array("status" => "OK", "file" => $file, "problem" => null))); 

安全風險:客戶端沿着文件名發送,任何文件名,並在腳本執行上的東西。一般你不知道誰是客戶端,或者誰可能是,所以你需要驗證文件名(例如:確定其基本名並在您首先發送)目標目錄確實存在:

if (!file_exists($yourDir . DIRECTORY_SEPARATOR . basename($file)) { 
    Header("Content-Type: application/json;charset=UTF-8"); 
    die(json_encode(array(
     "status" => "FAILED", 
     "file" => $file, 
     "problem" => "file could not be found", 
     /* "real-problem" => "Sorry, friend, it didn't work." */ 
    ))); 
} 

的陣列將返回到上面的JavaScript函數:

function(result) { 
    var msg; 
    if (result.status == "OK") { 
     msg = result.file + " OK"; 
    } else { 
     msg = result.file + ": " + result.problem 
    } 
    $('#logDiv').append($('<p>').text(msg)); 
} 

以上將改變一個HTML實體

<div id="logDiv"></div> 
,比如說

<div id="logDiv"> 
    <p>file1.pdf OK</p> 
    <p>file2.pdf: missing UUID entry</p> 
    ... 
</div> 

既然你知道了最初的filesToProcess.length,你也可以顯示一個進度條(甚至有像jQuery插件那樣簡單的$('#bar').progress(n*100/initialLength))。

或者,您可以通過發送兩個日誌線運行漫長的過程,一個之前的$。員額

$('#logDiv').append($('<p>').text("Parsing " + file)); 
0

您的意思是顯示結果而不刷新網頁? 如果那樣,你可以使用ajax發送請求。

+0

這個建議指向了正確的方向。我也建議你使用ajax並在ajax中提供一個回調函數,這樣你的php可以在生成它們時返回每個結果。然後,回調中的js代碼可以添加到包含結果的網頁上的數組中。 - 希望這可以幫助。 – JoelParke

+0

這個「答案」應該是一個評論。它真的沒有什麼回答實際問題 – nomistic

1

如果你只需要跟蹤你可以使用的error_log程序的執行($ FNAME)命令來代替'回聲'。較少的努力比AJAX,你可以通過貼在Ubuntu終端跟蹤執行「現場」:

tail -F /var/log/apache2/error.log 

(其他* nix的路徑可能會有所不同)。