2009-12-29 12 views
6

Tôi đã tạo tập lệnh tải xuống tệp bằng PHP, nó hoạt động nhưng trình duyệt web báo cáo tệp là "Độ dài không xác định". Mã của tôi như sau:Gửi kích thước tệp chính xác với tập lệnh tải xuống PHP

function downloadFile($file){ 
    // Set up the download system... 
    header('Content-Description: File Transfer'); 
    header('Content-Type: '.mime_content_type($file)); 
    header('Content-Disposition: attachment; filename="'.basename($file).'"'); 
    header('Content-Transfer-Encoding: binary'); 
    header('Expires: 0'); 
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); 
    header('Pragma: public'); 
    header('Content-Length: '.filesize($file)); 

    // Flush the cache 
    ob_clean(); 
    flush(); 

    // Send file to browser 
    readfile($file); 

    // DO NOT DO ANYTHING AFTER FILE DOWNLOAD 
    exit; 
} 

Trả lời

13

Nguyên từ http://paul.luminos.nl/update/471:

Các CrimsonBase website xác minh tải bằng cách đi qua chúng thông qua một kịch bản PHP mạnh mẽ tương tự như một xuất bản bởi Andrew Johnson trong his article about PHP-controlled file downloads.

Andrew làm cho một lời nhận xét rất quan trọng ở phần cuối của bài viết:

"Nếu bạn nén file với zlib, mod_deflate và vân vân header Content-Length sẽ không được chính xác, do đó bạn sẽ kết thúc nhìn thấy "Kích thước không xác định" và "Thời gian không xác định còn lại" khi tải xuống tệp. "

Tôi muốn nhấn mạnh điều này: nếu trình duyệt của bạn không xuất hiện để được tuân theo tiêu đề được tạo bởi PHP kịch bản, đặc biệt là Content-Length -đó là khá khả năng mở rộng mod_deflate Apache được kích hoạt.

Bạn có thể dễ dàng vô hiệu hóa nó cho một kịch bản duy nhất bằng cách sử dụng dòng sau trong một áp dụng .htaccess file:

SetEnvIfNoCase Request_URI ^/download\.php no-gzip dont-vary 

nơi download.php đang ở đây giả định là trong kịch bản tải nằm trong đường dẫn thư mục gốc của máy chủ (ví dụ: www.crimsonbase.com/download.php). (Đó là vì các biểu thức chính quy là ^/download\.php.)

+0

Thú vị. Tôi sẽ cần phải nhìn vào đó. –

+0

Cảm ơn bạn, tôi đã nhận được loại nội dung "gzip" trong bản tải xuống và có thể loại bỏ nó bằng dòng htaccess của mình, bây giờ tôi có thể xem lại tiến trình tải xuống vì tổng kích thước tệp được đọc chính xác bởi trình duyệt. – adrianTNT

0

Cố gắng không xóa bộ nhớ cache trước hàm readfile(). Mã của tôi gần giống với mã của bạn nếu không, và hoạt động tốt.

+0

Đã thử, không có gì. Tải xuống vẫn hoạt động tốt, nó chỉ là trình duyệt web sẽ nói "kích thước tệp không xác định" mặc dù tôi đã cung cấp cho nó một "Độ dài nội dung". Thing là, nếu tôi sử dụng wget, nó báo cáo kích thước tập tin chính xác. –

6

Tôi có vấn đề này giống nhau, và tôi cố định nó bằng cách gửi Content-Length tiêu đề trước khi Content-Disposition.

header('Content-Type: video/mp4'); 
header("Content-Transfer-Encoding: Binary"); 
header("Content-Length: ".filesize($file_url)); 
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\""); 
readfile($file_url);