2012-01-06 113 views
5

我在Windows 7 x64系統上使用PHP 5.2.4和Apache 2.2.17。我希望我的PHP頁面能夠實時向用戶的瀏覽器輸出system調用的結果。爲此,我已經配置在php.ini output_buffering=Off,並創造了這個代碼:實時輸出打印過程

<?php 
ob_implicit_flush(true); 
ob_end_flush(); 
system('ping -n 10 www.google.com'); 
?> 

平的結果打印實時的,但在頂我也得到一個PHP診斷錯誤和調用堆棧我的頁面上寫着:

Notice: ob_end_flush() [ref.outcontrol]: failed to delete and flush buffer. No buffer to delete or flush in index.php on line 3 

我需要做什麼來糾正或抑制此錯誤?

更新 如果我改變ob_end_flush()$a = 1/0;我收到了類似的錯誤,並且輸出在所有瀏覽器實時。打印異常的方式會導致這種情況發生嗎?

+2

刪除'ob_end_flush()函數;' – Grexis 2012-01-06 22:25:26

+0

如果我刪除或用@抑制,輸出不再是實時的Chrome 16或Firefox 10.(雖然它在IE9中工作) – PaulH 2012-01-06 22:29:14

+0

這很奇怪,但請參閱下面的答案。 – Grexis 2012-01-06 22:36:12

回答

6

某些Web瀏覽器緩衝第一x字節便開始呈現頁面之前,在一定條件下。

嘗試只輸出大量的空格第一

+0

是的。這是問題。謝謝! – PaulH 2012-01-09 18:45:05

+2

我不得不正確迴應894個字符到瀏覽器以啓用實時輸出。測試Firefox 21和IE 8。 – Clarkey 2013-06-08 11:28:49

0

在你的代碼中,錯誤很容易解釋。

您在第3行呼叫ob_end_flush(),但(如錯誤所述),沒有輸出要刷新。實質上,第3行是無用的,因爲沒有輸出已發送,所以刪除該行將修復錯誤。如果將其合併到較大的文件中,則可能需要保留ob_end_flush(),因爲某些輸出可能已被捕獲。

編輯:既然你需要刷新它,無論是:

答:加入ob_start();到文件的頂部。

B:與flush();

EDIT2更換ob_end_flush();:因爲第一似乎沒有工作,這是最好的,我可以提供:How to echo output in real time, (before script finishes)?

+0

如果我將其刪除,Chrome 16或Firefox 10中的輸出將不再實時。(儘管它在IE9中可以正常工作) – PaulH 2012-01-06 22:37:22

+0

每次編輯 - 使用更改A,它不會在任何瀏覽器中實時顯示。隨着變化B它只是在IE9實時。 – PaulH 2012-01-06 22:40:45

+0

@PaulH看看我鏈接的問題的答案。類似的,可能是同樣的問題。 – Grexis 2012-01-06 22:52:44

0

ob_end_flush()函數刷新PHP的輸出緩衝,並要求一個使用ob_start()創建的活動輸出緩衝區。

我想你只是想調用flush()來發送數據到客戶端。

<?php 
ob_implicit_flush(true); 
flush(); 
system('ping -n 10 www.google.com'); 
?> 
+0

使用此代碼,Chrome 16或Firefox 10中的輸出不是實時的。(儘管這可以在IE9中運行) – PaulH 2012-01-06 22:36:35

+0

我認爲瀏覽器(Chrome 16和ff10)在呈現文本之前緩存文本。我會使用javascript + ajax,一次獲得一個ping輸出並將其顯示給用戶。我會對強制頁面渲染的可靠方法感興趣... – al01 2012-01-06 22:57:32

+0

如果我願意忍受頁面頂部的異常對話框,我可以使其完美工作。我不認爲瀏覽器無法做到這一點。 – PaulH 2012-01-06 22:59:10

3

我有一個可行的解決方案,但它是非高性能和噁心。我拋出異常,但隱藏異常對話框。

<?php 
    ob_implicit_flush(true); 

    // Something about the way exceptions are thrown causes Firefox and Chrome 
    // to be able to display the results of the system call in real-time rather 
    // than having to wait for the call to complete. So, I just hide the 
    // exception message. IE9 works with or without this. 
    echo "<div style=\"display:none\">"; 
    $a = 1/0; 
    echo "</div>"; 

    echo "<pre>"; 
    system('ping -n 5 www.google.com'); 
    echo "</pre>"; 
?> 

要自動滾動到頁面的底部,我添加了一些javascript:

<html><head> 
<script language="javascript"> 
var int = self.setInterval("window.scrollBy(0,1000);", 200); 
</script> 
</head> 
<body> 
<?php 
    // insert above php code here 
    // stop scrolling when the execution finishes 
    echo '<script language="javascript">int = window.clearInterval(int);</script>'; 
?> 
</body> 
</html> 

編輯

@克里斯的回答顯示了一個更好的解決方案。

echo '<div style="display:none">'; 
for ($a = 0; $a < 768; $a++) 
    echo ' '; 
echo '</div>'; 
1

只需添加這刷新緩衝區:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) { 
     echo "<div style=\"display:none\">"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";  
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";  
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
      echo "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"; 
     echo "</div>"; 
    } 

它必須是在循環中。或者您需要實時顯示的兩個輸出之間。

而這裏的速記技巧:

補充一點:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) { 
    echo "<div style=\"display:none\"></div>";      
}