2009-10-13 39 views
7

Câu hỏi của tôi là - Cách tốt nhất có thể để phát hiện xem tải xuống có hoàn tất không, vì sau đó tôi muốn cập nhật cơ sở dữ liệu.kiểm tra xem tải xuống đã hoàn tất chưa

Tôi đã thử một số mã này từ php manuel, nhưng nó không làm được gì nhiều cho tôi.

Header ("Content-Type: application/octet-stream"); 
Header ("Content-Length: ".filesize($file)); 
Header("Content-Disposition: attachment; filename=$filename"); 

// buffered read not using readfile($file); 

if ($fp = fopen($bestand, 'rb')) { 
    while (!feof($fp)) { 
     $buf = fread($fp, 4096); 
     echo $buf; 
     $bytesSent += strlen($buf); /* We know how many bytes were sent to the user */ 
    }  
} 

if ($bytesSent == filesize($fp)) { 
    //do something with db 
} 

nhờ ở ADV, Richard

+0

im tìm thấy một giải pháp tốt thực hiện PHP tinh khiết: http://bytes.com/topic/php/answers/551302-how-detect-if-file-download-completed- hủy bỏ – StefanoCudini

Trả lời

9

Điều đó không thực sự cho bạn biết liệu tải xuống đã hoàn tất cho người dùng hay chưa. Nó sẽ cho bạn biết khi nào bạn đã hoàn thành việc gửi byte cho người dùng, nhưng nó không nói gì về số lượng người dùng thực sự đã nhận được.

Trong thực tế, không có cách nào với PHP (là phía máy chủ, không phải là phía máy khách, ngôn ngữ) để thực sự phát hiện khi tải xuống tệp hoàn tất. Điều tốt nhất bạn có thể làm là ghi nhật ký tải xuống trong cơ sở dữ liệu của bạn khi nó bắt đầu. Nếu bạn hoàn toàn, hoàn toàn và hoàn toàn cần phải biết khi tải xuống đã hoàn tất, bạn sẽ phải làm điều gì đó như nhúng một applet Java hoặc sử dụng Flash. Tuy nhiên, thông thường đó không phải là câu trả lời chính xác về khả năng sử dụng cho người dùng của bạn (tại sao yêu cầu họ phải cài đặt Java hoặc Flash để tải xuống thứ gì đó từ bạn?).

+0

có, tôi đã thực hiện điều đó và đã gửi lại thư để liên hệ với tôi nếu có sự cố. Tôi cũng sử dụng một plugin jquery để có được một cuộc gọi lại khi hoàn thành và tôi không có làm mới trang. – Richard

+0

http://php.net/function.ignore_user_abort - http://www.php.net/connection_aborted – hakre

+0

@hakre cho connection_aborted từ doc: Khi chạy PHP dưới dạng tập lệnh dòng lệnh (tty). – Mike

1

Tôi không nghĩ rằng nó có thể qua php biết có bao nhiêu cắn đã được gửi ra (và thực sự tải về thông qua client), vì không có cách nào để biết nếu người dùng đã hủy tải xuống hoặc nhận toàn bộ tệp.

+0

Và có máy chủ web inbetween. PHP không có quyền kiểm soát nó. – powtac

+1

Ngoài ra, một proxy ở đầu của người dùng có thể hoàn tất việc tải xuống ngay cả khi người dùng đã hủy nó –

+0

cảm ơn, Gnibbler. Sau đó, nói rằng tất cả. Nó không phải là một cách đáng tin cậy. – Richard

2

Như Marc W đã chỉ ra php chỉ có thể cho bạn biết những gì bạn đã gửi từ máy chủ, không phải những gì khách hàng nhận được, do đó, sử dụng đúng php là không khởi động.

Nhưng luôn có khả năng yêu cầu người dùng xác nhận tải xuống bằng cách nhấn nút gọi kiểm tra JS bằng cách tạo mã băm MD5 và so sánh với mã băm MD5 của tệp trên máy chủ của bạn (trên máy chủ MD5 được tạo ra bởi bạn), và trên một sử dụng so sánh thành công kịch bản JS để cập nhật db của bạn hoặc sử dụng nó để gọi một tập lệnh php để làm như vậy.

Bạn luôn có thể yêu cầu họ kiểm tra tải xuống là những gì họ mong đợi và, nếu họ nhấn "có, thì tốt" thì hãy cập nhật cơ sở dữ liệu.


Đã chỉnh sửa: để trả lời nhận xét của OP.

Cảm ơn bạn, nhưng bạn không thể phụ thuộc vào tính hợp tác của người dùng. Bởi vì họ cũng phải trả tiền cho việc tải xuống, nó là tốt hơn mà tôi có tất cả các controll.I nghĩ rằng tôi sau đó sẽ cập nhật cơ sở dữ liệu khi kịch bản được truy cập. Điều đó có vẻ là đáng tin cậy nhất sau đó.

Làm thế nào về việc sử dụng điều khiển Ajax để bắt đầu và duy trì tải xuống, và khi hoàn thành xác minh tính toàn vẹn của nó và chạy bản cập nhật cho db của bạn?

Tôi khuyên bạn không nên tự động giả định khách hàng của bạn sẽ tách bạn ra, mặc dù, bất kỳ điều gì bạn chọn. Yêu cầu họ độc đáo 'nó có hiệu quả với bạn không?' và, nếu không, dẫn đến báo cáo lỗi có thể hữu ích cho bạn và họ.

Nhưng, bất kể, trong khi một số người dùng của bạn có thể nói 'không' chỉ cho bản sao bổ sung, bạn phải cân bằng chi phí so với chi phí khối lượng công việc tăng của mình để ngăn việc xảy ra. Nếu chi phí duy trì 'trung thực' vượt quá khả năng/khả năng chi phí của việc họ lấy thêm một bản sao, thì có rất ít điểm.

+0

Cảm ơn, nhưng bạn không thể phụ thuộc vào sự hợp tác của người dùng. Bởi vì họ cũng phải trả tiền cho việc tải xuống, nó là tốt hơn mà tôi có tất cả các controll.I nghĩ rằng tôi sau đó sẽ cập nhật cơ sở dữ liệu khi kịch bản được truy cập. Điều đó có vẻ là đáng tin cậy nhất sau đó. – Richard

+0

Cảm ơn bạn đã thêm đầu vào, nhưng bạn đã chạy qua thực tế là bạn đã đề cập rằng có một cách ajax. Bạn có một ví dụ cho điều đó? – Richard

+0

Thật không may, tôi không. Tôi không biết JS/jQuery/Ajax đủ tốt để đưa ra giải pháp. Có thể bạn cần chỉnh sửa câu hỏi ban đầu của mình để đưa vào yêu cầu và gắn thẻ lại cho các giải pháp Ajax, JS và/hoặc jQuery. Tôi xin lỗi tôi không thể được sử dụng nhiều hơn cho bạn trong này. –

-4

Mã sau hoạt động.Nếu chương trình tải xuống bị dừng bởi máy khách, cơ sở dữ liệu không được cập nhật và liên kết có thể kích hoạt lại.

$file='pathto.zip'; 

    header("Content-type: application/zip"); 
    header("Content-Disposition: attachment; filename=$file"); 
    header("Pragma: no-cache"); 
    header("Expires: 0"); 
    readfile("$file"); 

    $sql = "UPDATE YOUR TABLE"; 

    exit; 
+0

Điều này không hoạt động. 'readfile' không thể biết liệu người dùng có bị hủy hay không. Nó trả về không có lỗi, giả sử tệp đủ nhỏ để vừa với bộ đệm đầu ra trong một lần, và sau đó mã sẽ tiến hành cập nhật cơ sở dữ liệu. Không có gì được truyền lên từ lớp TCP để chỉ ra sự phân phối đến phía bên kia của đường ống. –

+0

Tính năng này không hoạt động. – Mike

+0

Điều này không hoạt động nữa. –

0

Có một giải pháp nếu bạn đang trộn php (cho cuộc gọi phía máy chủ) một javascript (cho cuộc gọi hoàn thành của khách hàng).

Look câu trả lời này về cách Detect when browser receives file download

Tôi khá chắc chắn rằng bạn có thể có một kết quả tốt như thế này. Tôi hy vọng điều này giúp đỡ người khác, Mike

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