PHP實現前臺同步顯示後臺任務進度

 這兩天需要給公司開發一個短信發送提醒的功能,一次批量發送幾千條短信。
如果直接在後臺循環執行雖然可行,但是前臺操作用戶就只能坐着空等,完全看不到後臺執行結果,所以考慮能不能有一種辦法可以在php後臺執行過程中同時在前臺顯示後臺執行任務進度呢。
但是這裏遇到一個問題,一般情況下php都是在後臺任務執行完畢後輸出結果到瀏覽器,在執行過程不會給瀏覽器發送任何數據。這個時候想到了可以使用php的flush函數,可以使用flush函數在程序執行中強制輸出;
嘗試以下代碼:

?
	
<?php
for($i= 1;$i<= 50;$i++) {
 ob_flush();
 flush();
 echo$i.'<br/>';
 sleep(rand(0, 1));
}
?>

網上大都這樣的例子,看代碼應該會每隔一秒輸出一個數字。但是大家實際測試下情況並非如此,而是和沒用flush一樣,一次性輸出1-50;
在這裏請大家參考下鳥哥博客上的一篇文章http://www.laruence.com/2010/04/15/1414.html( 深入理解ob_flush和flush的區別);
其中有一段話:

有些Apache的模塊,比如mod_gzip,可能自己進行輸出緩存,這將導致flush()函數產生的結果不會立即被髮送到客戶端瀏覽器。 

甚至瀏覽器也會在顯示之前,緩存接收到的內容。例如 Netscape瀏覽器會在接受到換行或 html 標記的開頭之前緩存內容,並且在接受到 </table> 標記之前,不會顯示出整個表格。 

一些版本的 Microsoft Internet Explorer 只有當接受到的256個字節以後纔開始顯示該頁面,所以必鬚髮送一些額外的空格來讓這
些瀏覽器顯示頁面內容。

所以找到問題所在了,不是因爲flush沒有起作用,而是服務器或者瀏覽器在內容不到一定的字節數(甚至是沒有遇到html標記)同樣會進行緩存,找到問題所在後嘗試以下代碼;

<?php
echostr_repeat("<b></br>",4096);//隨便輸出一段代碼立即輸出
for($i= 1;$i<= 50;$i++) {
ob_flush();
flush();
echo$i.'<br/>';
sleep(rand(0, 1));
}
?>

已經可以將後臺數據實時發送到前臺了,然後有辦法了嗎?結合js,每次循環都輸出一段js,去操作html節點;附上disucz中提出出來的安裝進度代碼供大家參考吧
	
<html xmlns="http://www.w3.org/1999/xhtml"><head>
<meta content="text/html; charset=utf-8"http-equiv="Content-Type">
<title>Discuz! 安裝嚮導</title>
<style type="text/css">
body{ padding:5px 0; background:#FFF; text-align:center; }
body, td, input, textarea, select, button{ color:#666; font:12px/1.5 Verdana, Tahoma, Arial,'Microsoft Yahei','Simsun', sans-serif; }
.container{ overflow:hidden; margin:0 auto; width:700px; height:auto !important;text-align:left; border:1px solid #B5CFD9; }
.main{ padding:20px 20px 0; background:#F7FBFE url(bg_repx.gif) repeat-x 0 -194px; }
    .main h3{ margin:10px auto; width:75%; color:#6CA1B4; font-weight:700; }
#notice { overflow: hidden; margin: 20px; padding: 5px; height: 300px; border: 1px solid #B5CFD9; text-align: left; }
</style>
<meta name="Copyright"content="Comsenz Inc.">
</head>
<body><div>
<div><script type="text/javascript">
functionshowmessage(message) {
    document.getElementById('notice').innerHTML += message +'<br/>';
    document.getElementById('notice').scrollTop = 100000000;
}
</script>
        <div id="notice"></div>
<?php
//檢測完成後顯示的信息
functionshowjsmessage($message) {
    echo'<script type="text/javascript">showmessage(\''.addslashes($message).' \');</script>'."\r\n";
    flush();
    ob_flush();
}
  
//模擬初始化數據表
for($i= 1;$i<= 50;$i++) {
    showjsmessage("建立數據表 {$i} ... 成功");
    sleep(rand(0, 1));
}
  
?>
</div>
</div>
</body>
</html>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章