2010-08-10 46 views
5

Tôi đang cố gắng chạy vòng lặp mỗi giây trong 25 giây về cơ bản.đầu ra php với chế độ ngủ()

for($i = 0; $i <= 25; $i += 1){ 
    echo $i; 
    sleep(1) 
} 

Điều này không được xuất ra cho đến khi hoàn thành xong, vì vậy sau khi vòng lặp tiếp tục 25 lần. Có cách nào để làm điều này vì vậy nó sẽ ra trước mỗi giấc ngủ? và không đợi cho đến khi toàn bộ vòng lặp hoàn tất?

Cảm ơn!

+0

Trình duyệt và nội dung của bạn là gì? Một số trình duyệt sẽ không hiển thị HTML cho đến khi chúng gặp phải thẻ đóng. Văn bản thuần túy có thể là một lựa chọn tốt hơn nếu bạn muốn nội dung "cập nhật trực tiếp". – mwalker

+1

Điều này có vẻ như một vấn đề được xử lý tốt hơn ở phía khách hàng. Bạn có thể lấy từ máy chủ bằng cách sử dụng AJAX mỗi giây. –

+2

đây là điều hoàn toàn không nên thực hiện theo cách bạn đang cố gắng trên máy chủ .. sử dụng một số ajax và setTimeout hoặc như vậy trong trình duyệt thay thế .. –

Trả lời

4

Gọi flush sẽ buộc PHP đẩy tất cả bộ đệm đầu ra cho ứng dụng trước khi tiếp tục.

for($i = 0; $i <= 25; $i += 1){ 
    echo $i; 
    flush(); 
    sleep(1); 
} 

EDIT:

Sau khi thử nghiệm này trên máy chủ lighttpd tôi nhận thấy rằng nó đệm đầu ra của tôi trong khối 4096 ký tự, và tôi giả sử trình duyệt khác có thể có phương án đệm tương tự. Ngoài ra GZIP có thể ngăn chặn hoàn toàn flush. Thật không may là không có cách nào để kiểm tra rằng nó hoạt động do bản chất của HTTP.

Ngoài ra một vấn đề khác với chiến lược này là nó để lại rằng PHP proc bị chặn cho các yêu cầu khác. Điều này có thể khiến các yêu cầu chồng chất lên.

+0

Hmm .. Dường như không thực hiện thủ thuật .. cũng đã thử w/ob_start(), ob_flush() và flush() – dzm

+1

Thông thường, combo của 'ob_end_flush() '(bỏ qua' ob_start() ') và' flush() 'thực hiện nó. Bạn có máy chủ proxy giữa bạn và máy chủ đang chạy PHP không? –

+0

Làm việc cho tôi chạy qua dòng lệnh, nhưng không phải trình duyệt ... sau khi tôi đặt dấu chấm phẩy sau khi ngủ (1) –

8

Những gì bạn đang cố gắng đạt được là đầu ra gia tăng cho trình duyệt từ PHP.

Cho dù điều này có thể đạt được có thể phụ thuộc vào máy chủ của bạn và cách bạn đang gọi PHP.

PHP dưới FastCGI

Bạn đang có lẽ khả năng chạy vào loại vấn đề khi PHP đang chạy dưới FastCGI chứ không phải như một module Apache hơn một chút, bởi vì các khớp nối giữa máy chủ và các quy trình PHP không được kết hợp chặt chẽ. FastCGI truyền thông sử dụng đầu ra đệm một khi dữ liệu đã để lại các quy trình PHP, với đầu ra được gửi đến trình duyệt chỉ khi yêu cầu hoàn toàn đầy đủ, hoặc bộ đệm này đã được lấp đầy. Ngày đầu này, các quá trình PHP có xu hướng được chấm dứt sau một khoảng thời gian nhất định, để tránh cho phép bất kỳ một quá trình chạy quá lâu.

Điều đó nói rằng, sự kết hợp của ob_end_flush() (hoặc ob_flush()) và flush() vẫn nên khiến PHP yêu cầu bộ đệm hạ lưu bị xóa, vì vậy điều này có thể vẫn hoạt động. Bạn cũng có thể cần điều tra xem bạn có cần phải kéo dài thời gian cho các tập lệnh PHP hay không.

PHP dưới mod_php

Nếu bạn đang sử dụng mod_php, bạn có thể viết từng bước ra để trình duyệt. Sử dụng lệnh flush() để đảm bảo rằng mô-đun PHP sẽ xóa nó ngay lập tức. Nếu bạn không có bộ đệm đầu ra, hoặc một số mô đun Apache như mod_gzip, thì nó sẽ xuất hiện ngay lập tức cho trình duyệt của người dùng. Hơn nữa, bạn có thể giữ cho kịch bản PHP của bạn chạy miễn là bạn thích (với set_time_limit() trong PHP), theo các cấu hình mặc định, mặc dù tất nhiên nó sẽ tiêu thụ một số bộ nhớ.

Bạn có thể gặp sự cố với một số trình duyệt không bắt đầu hiển thị trang cho đến khi số lượng trang nhất định được tải xuống. Một số phiên bản của IE có thể chờ 1KB. Tôi thấy rằng Chrome có thể chờ đợi nhiều hơn. Rất nhiều người xung quanh điều này bằng cách thêm đệm, chẳng hạn như một bình luận dài 1 hoặc 2 KB dài ở phía trên cùng của tài liệu.

3

Tôi chỉ băm thông qua cùng một vấn đề này từ góc độ người mới bắt đầu và đã đưa ra kịch bản xương trần này sẽ làm những gì bạn muốn.

<?PHP 
ob_start(); 
$buffer = str_repeat(" ", 4096)."\r\n<span></span>\r\n"; 

for ($i=0; $i<25; $i++) { 
    echo $buffer.$i; 
    ob_flush(); 
    flush(); 
    sleep(1); 
} 

ob_end_flush(); 
?> 

câu hỏi mà bạn có thể yêu cầu có thể là here (khoảng \r\n) và here (khoảng ob_flush()). Hy vọng điều đó giúp được bạn.

Các vấn đề liên quan