2012-03-15 19 views
5

Tôi có một đối tượng cho nhiệm vụ và trên __deconstruct(), nó có nghĩa là chạy một số tác vụ dọn dẹp dài hơn sau khi phần còn lại của trang đã được tải. Thật không may, nó đệm đầu ra và sẽ không gửi nó cho đến khi các tác vụ được hoàn thành (không có gì được in trong các tác vụ).Vô hiệu hóa bộ đệm đầu ra trong PHP

Tôi đã đọc qua http://www.php.net/flush và đã thử tất cả các đề xuất ở đó. Rõ ràng là tôi đã thử vô hiệu hóa output_buffering trong php.ini. Tôi đã vô hiệu hóa deflate_module, nén zlib bị tắt, không có mod_gzip. Gọi flush() hoặc ob_flush() không có hiệu lực, cũng như không cho phép implicit_flush.

Tôi chỉ đang chạy XAMPP (hiện tại là apache 2.2.17, php 5.3.4) trong Windows Server 2008 R2. PHP đang được chạy như một mô-đun. Và có, tôi có thể thiết lập một số AJAX hack nhỏ để chạy trình quản lý tác vụ hoặc thậm chí thiết lập một tác vụ theo lịch trình để chạy tác vụ cụ thể này, nhưng bộ đệm đầu ra cũng là một vấn đề ở nơi khác. Đôi khi chỉ muốn nó biến mất.

Từ một sợi tương tự, có người đề nghị nhìn thấy những gì sau đây sẽ làm:

<?php 
while (TRUE) 
{ 
    echo 'x'; 
    flush(); 
    sleep(1); 
} 
?> 

Đúng như dự đoán, các trang hiển thị không có gì cho đến khi thời gian thực hiện tối đa đạt được, lúc này nó flushes bộ đệm.

Điều này đã trở nên cực kỳ bực bội. Bất cứ ai có bất kỳ ý tưởng những gì vẫn có thể gây ra nó để đệm?

+0

Bạn có thể xác nhận rằng đầu ra vẫn nhận được đệm so với trình duyệt không hiển thị bất kỳ thứ gì (ví dụ: IE sẽ không hiển thị gì cho đến khi nó nhận được một số byte)? –

+0

thực hiện chức năng này http://php.net/manual/en/function.ob-get-level.php return 0? – dqhendricks

+0

bạn có thể thử điều này nếu nó giúp http://in3.php.net/manual/en/function.ob-end-flush.php –

Trả lời

4

Bạn chỉ gửi một lượng nhỏ dữ liệu. Các trình duyệt có bộ đệm riêng của chúng, có thể dựa trên một số byte, theo đó các phần tử đã được nhận hoặc bởi một số thứ khác.

Tóm lại, bạn không thể làm gì về điều này. Bộ đệm đang xảy ra phía máy khách, chứ không phải phía máy chủ. Bạn có thể thử gửi thêm dữ liệu trước số x của mình.

Bạn có thể chứng minh điều này bằng gói sniffing kết nối giữa máy chủ và trình duyệt, với Wireshark hoặc tương tự.

+0

Vâng, tôi sẽ nói rằng tôi đã gửi một chút công bằng của dữ liệu trước, nhưng khi thay đổi nó để cho ($ i = 0; $ i <10000; $ i + +) {echo 'x
'; ngủ (1) }, nó kết quả tốt. Tôi đoán cách giải quyết duy nhất sẽ gửi nhiều dữ liệu hơn để buộc trình duyệt hiển thị nó. Có thể không lý tưởng. Cảm ơn, mặc dù. Tôi tiếp tục đọc kịch bản và cấu hình của mình và điều đó khiến tôi phát điên. – Apropos

+0

IE được biết đến với điều này. Tôi đã gạt IE bằng cách gửi khoảng 1000 dấu cách trước khi xả. Bởi vì HTML conflates không gian nó không quan trọng. – nalply

4

hmmm, thú chộp lấy một snip mã tôi đã sử dụng những nơi khác và nó hoạt động như mong đợi ...

https://stackoverflow.com/a/9728519/632951 

<?php 
echo str_repeat('fillerbytes',20*1024/strlen('fillerbytes')); 
echo '<body style="font-size:6px;font-family:arial;">'; 
echo str_repeat('<br>',2); 
    for($i=1; $i<=5000; $i++){ 
     echo $i . ' '; 
     ob_flush(); 
     flush(); 
     usleep(2000); // 2 ms each = 10s total 
    } 
?> 

Xem count máy chủ của tôi để 5000 http://atwebresults.com/texttest/new.php

(Không hoạt động trên một số host miễn phí như freehostingeu.com.)

+0

Có, tính năng này hoạt động. Thật không may, nó chỉ vì nó gửi nhiều dữ liệu hơn tôi muốn gửi. Thay đổi thời gian giữa các lần lặp thành 1 thay vì .001 làm cho hành vi không mong muốn trở lại. – Apropos

+0

Điều này làm cho ngày của tôi. Tôi nghĩ rằng nó hoạt động vì việc sử dụng ob_flush(); thay vì flush(); – Alrik

+0

Đó là do lượng dữ liệu được gửi, chứ không phải ob_flush(). Ví dụ ban đầu không thành công ngay cả khi thêm ob_flush(), hoặc điều này không thành công khi thay đổi thời gian giữa các lần lặp thành 1s thay vì một phần nghìn giây như hiện tại. – Apropos