2012-01-06 50 views
5

Tôi đang sử dụng PHP 5.3.4 với Apache 2.2.17 trên hệ thống Windows 7 x64. Tôi muốn có trang PHP của tôi xuất kết quả của một cuộc gọi system trong thời gian thực tới trình duyệt của người dùng. Cuối cùng, tôi đã cấu hình output_buffering=Off trong php.ini và tạo ra mã này:quá trình in ra trong thời gian thực

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

Kết quả của lệnh ping được in trong thời gian thực, nhưng tôi cũng nhận được một lỗi chẩn đoán PHP và callstack ở đầu trang của tôi có nội dung:

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

Tôi cần phải làm gì để sửa hoặc loại bỏ lỗi này?

Cập nhật Nếu tôi thay đổi ob_end_flush() để $a = 1/0; tôi nhận được một lỗi tương tự và kết quả là thời gian thực trong tất cả các trình duyệt. Có một cái gì đó về cách ngoại lệ được in mà gây ra điều này để làm việc?

+2

Remove 'ob_end_flush(); ' – Grexis

+0

Nếu tôi loại bỏ nó hoặc ngăn chặn với @, đầu ra là không còn thời gian thực trong Chrome 16 hoặc Firefox 10. (Mặc dù, nó hoạt động trong IE9) – PaulH

+0

Thật lạ lùng, nhưng hãy xem câu trả lời của tôi bên dưới. – Grexis

Trả lời

6

một số web trình duyệt đệm đầu tiên x byte trước khi họ bắt đầu làm cho một trang, dưới những điều kiện nhất định.

thử rất nhiều chỉ xuất ra các khoảng trắng

đầu tiên
+0

Yup. Đây là vấn đề. Cảm ơn bạn! – PaulH

+2

Tôi phải lặp lại chính xác 894 ký tự cho trình duyệt để cho phép đầu ra thời gian thực. Thử nghiệm trên Firefox 21 và IE 8. – Clarkey

0

Trong mã của bạn, lỗi này khá dễ hiểu.

Bạn gọi ob_end_flush() trên dòng 3, nhưng (giống như lỗi nói), không có đầu ra để tuôn ra. Về bản chất, dòng 3 là vô dụng vì không có đầu ra nào được gửi đi, vì vậy việc xóa dòng sẽ sửa lỗi. Nếu điều này được tích hợp vào một tệp lớn hơn, bạn có thể cần phải giữ ob_end_flush() vì một số đầu ra có thể đã được chụp.

EDIT: Vì bạn cần phải tuôn ra nó, hoặc là:

a: thêm ob_start(); để phía trên cùng của tập tin.

b: thay thế ob_end_flush(); với flush();

EDIT2: Kể từ khi lần đầu tiên dường như không làm việc, đây là tốt nhất mà tôi có thể cung cấp: How to echo output in real time, (before script finishes)?

+0

Nếu tôi xóa nó, đầu ra không còn là thời gian thực trong Chrome 16 hoặc Firefox 10. (Mặc dù, nó hoạt động trong IE9) – PaulH

+0

cho mỗi chỉnh sửa của bạn - Với thay đổi A, nó không phải là thời gian thực trong bất kỳ trình duyệt nào. Với thay đổi B, đó là thời gian thực chỉ trong IE9. – PaulH

+0

@PaulH Hãy xem câu trả lời cho câu hỏi tôi đã liên kết. Tương tự, và có lẽ cùng một vấn đề. – Grexis

0

ob_end_flush() flushes bộ đệm đầu ra php, và đòi hỏi một bộ đệm đầu ra hoạt động được tạo với ob_start().

Tôi nghĩ bạn chỉ muốn gọi flush() để gửi dữ liệu cho khách hàng.

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

Với mã này, đầu ra không phải là thời gian thực trong Chrome 16 hoặc Firefox 10. (Mặc dù điều này không hoạt động trong IE9) – PaulH

+0

Tôi nghĩ rằng các trình duyệt (Chrome 16 và ff10) đang lưu trong bộ nhớ đệm văn bản trước khi hiển thị nó. Tôi muốn đi với javascript + ajax, nhận được một đầu ra ping vào thời gian và hiển thị nó cho người dùng. Tôi muốn được quan tâm một cách đáng tin cậy để buộc các trang rendering quá ... – al01

+0

Tôi có thể làm cho nó hoạt động hoàn hảo nếu tôi sẵn sàng đưa lên với một hộp thoại ngoại lệ ở đầu trang. Tôi không nghĩ rằng các trình duyệt không có khả năng làm điều này. – PaulH

3

tôi có một giải pháp mà làm việc, nhưng nó là không performant và icky. Tôi ném một ngoại lệ, nhưng ẩn hộp thoại ngoại lệ.

<?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>"; 
?> 

Để tự động di chuyển đến dưới cùng của trang, tôi thêm một số 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> 

EDIT

@ câu trả lời của Chris cho thấy một giải pháp tốt hơn nhiều.

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

Chỉ cần thêm này để tuôn ra bộ đệm:

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>"; 
    } 

Nó phải được bên trong vòng lặp. hoặc giữa hai đầu ra bạn cần hiển thị trong thời gian thực.

VÀ đây là một mánh khóe viết tắt:

thêm này:

if (eregi("chrome",$_SERVER['HTTP_USER_AGENT'])) { 
    echo "<div style=\"display:none\"></div>";      
} 
Các vấn đề liên quan