2012-05-29 52 views
0

我試圖編寫一個ping幾百個地址並返回它們的值(毫秒)的函數。到目前爲止,我已經實現了最初的想法,即ping和獲得結果,但是當爲數百個地址使用相同的代碼時會出現問題,PHP頁面會暫停,直到它超時或達到最後的ping命令。逐步輸出exec()ping結果

我會很高興,如果我能得到一些建議,以逐步輸出的結果,這裏是我當前的代碼:

<?php 

// "for" loop added according to suggestion for browser compatibility (IE, FF, CHR, OPR, SFR) 
for($i = 0; $i < 5000; $i++) 
{ 
    echo ' '; 
} 

function GetPing($ip = NULL) { 
    // Returns the client ping if no address has been passed to the function 
    if(empty($ip)) { 
     $ip = $_SERVER['REMOTE_ADDR']; 
    } 

    // Check which OS is being run by the client 
    if(getenv('OS') == 'Windows_NT') { 
     //echo '<b>Detected local system:</b> Windows NT/2000/XP/2003/2008/Vista/7<p>'; 
     $exec = exec("ping -n 1 -l 32 -i 128 " . $ip); 
     return end(explode(' ', $exec)); 
    } 
    else { 
     //echo '<b>Detected local system:</b> Linux/Unix<p>'; 
     $exec = exec("ping -c 1 -s 32 -t 128 " . $ip); 
     $array = explode('/', end(explode('=', $exec))); 
     return ceil($array[1]) . 'ms'; 
    } 
    // ob_flush and flush added according to suggestion for buffer output 
    ob_flush(); 
    flush(); 
} 

// Added to test 20 sequential outputs 
for($count = 0; $count < 20; $count++) 
    echo GetPing('8.8.8.8') . '<div>'; 

?> 

一些反饋後,我添加了一個循環以及使用ob_flush ()和flush()到我的腳本,我也設置output_buffering爲0在php.ini。它似乎適用於目前爲止我測試過的大多數瀏覽器(IE8,Firefox 12,Chrome 19,Opera 11,Safari 5)。目前的代碼似乎正在按預期工作,但任何改進它的建議都非常值得讚賞。

感謝您的反饋。

+0

看看[** fping **](http://fping.sourceforge.net/)。它比傳統的ping更容易處理多個主機的ping操作,並且更容易通過軟件解析船隻輸出。 – ghoti

回答

1

這只是一種猜測;我幾年前寫了一個非常搖擺不定的聊天腳本,它也使用輸出緩衝(並在while(true)循環中獲取新消息)。

雖然這樣做我遇到了相同的問題,有時腳本會停滯(空白屏幕),有時需要一段時間,直到字符出現,另外這也是瀏覽器特定的。

下面是相關的代碼片段,我添加到腳本把它與IE6和FF2的工作(正如我所說,年前...)

<?php 
    // End output buffering 
    ob_end_flush(); 

    // IE and Safari Workaround 
    // They will only display the webpage if it's completely loaded or 
    // at least 5000 bytes have been "printed". 
    for($i=0;$i<5000;$i++) 
    { 
     echo ' '; 
    } 

    while(...) 
    { 
     echo 'Message'; 
     ob_flush(); 
     flush(); 
    } 
?> 

它爲我工作,所以也許你也可以嘗試一下。 (儘管我不知道現代瀏覽器和服務器infrastrucutre會如何表現)。

+0

非常感謝GeneSys,「for」循環對於解決問題至關重要,在測試過程中,我有時必須關閉瀏覽器並重新打開瀏覽器才能正常工作。它使用以下瀏覽器:IE8,Firefox 12,Chrome 19,Opera 11.我更新了代碼以反映實際情況。謝謝。 – ner0

+0

太棒了:)我很高興它按預期工作:) – GeneSys

+0

它現在給出了這個錯誤:注意:ob_flush():無法刷新緩衝區。沒有緩衝區來沖洗 –

0

我認爲你可能正在尋找的是逐步運行和輸出腳本,而不是異步功能。

Is there a way to make PHP progressively output as the script executes?

+0

感謝您的提示nomaD,但我一直無法正常工作。首先,我在php.ini中將output_buffering設置爲0,並且更新了代碼以包含ob_flush()和flush()。儘管我知道在沒有ob_start()之前不應該使用ob_flush(),但它是實現步進式輸出結果的唯一方式,但僅僅是因爲PHP會輸出警告通知:注意:ob_flush()[ref.outcontrol]:無法刷新緩衝區。沒有緩衝區來沖洗。奇怪的是,如果我修復代碼幷包含ob_start(),那麼我將不會像以前那樣得到任何實時輸出。 – ner0