一般的文件安全下载方法可以使用下面的代码: 1. <?php? 2. 3. $durl = 'file/phpcms2008_o2abf32efj883c91a.iso'; 4. $filename = 'phpcms2008_o2abf32efj883c91a.iso'; 5. $file = @fopen($durl, 'r'); 6. header("Content-Type: application/octet-stream"); 7. header("Accept-Ranges: bytes"); 8. header("Accept-Length: ".filesize($durl)); 9. header("Content-Disposition: attachment; filename=".$filename); 10. echo fread($file,filesize($durl)); 11. fclose($file); 12. ?> 但是文件一大(超过php.ini配置的内存最大值),这里就出问题了,服务器会非常占用CPU资源,更重要的是文件不能正常下载,只能下载几十Kb的文件,明显不是预期想要的。 1. function download($url, $filename) { 2. 3. // 获得文件大小, 防止超过2G的文件, 用sprintf来读 4. $filesize = sprintf ( "%u", filesize ( $url ) ); 5. if (! $filesize) { 6. return; 7. } 8. header ( "Content-type:application/octet-stream/n" ); //application/octet-stream 9. header ( "Content-type:unknown/unknown;" ); 10. header ( "Content-disposition: attachment; filename=/"" . $filename . "/"" ); 11. header ( 'Content-transfer-encoding: binary' ); 12. if ($range = getenv ( 'HTTP_RANGE' )) { // 当有偏移量的时候,采用206的断点续传头 13. $range = explode ( '=', $range ); 14. $range = $range [1]; 15. 16. header ( "HTTP/1.1 206 Partial Content" ); 17. header ( "Date: " . gmdate ( "D, d M Y H:i:s" ) . " GMT" ); 18. header ( "Last-Modified: " . gmdate ( "D, d M Y H:i:s", filemtime ( $url ) ) . " GMT" ); 19. header ( "Accept-Ranges: bytes" ); 20. header ( "Content-Length:" . ($filesize - $range) ); 21. header ( "Content-Range: bytes " . $range . ($filesize - 1) . "/" . $filesize ); 22. header ( "Connection: close" . "/n/n" ); 23. } else { 24. header ( "Content-Length:" . $filesize . "/n/n" ); 25. $range = 0; 26. } 27. loadFile ( $url ); 28. } 29. 30. function loadFile($filename, $retbytes = true) { 31. $buffer = ''; 32. $cnt = 0; 33. $handle = fopen ( $filename, 'rb' ); 34. if ($handle === false) { 35. return false; 36. } 37. while ( ! feof ( $handle ) ) { 38. $buffer = fread ( $handle, 1024 * 1024 ); 39. echo $buffer; 40. ob_flush (); 41. flush (); 42. if ($retbytes) { 43. $cnt += strlen ( $buffer ); 44. } 45. } 46. $status = fclose ( $handle ); 47. if ($retbytes && $status) { 48. return $cnt; // return num. bytes delivered like readfile() does. 49. } 50. return $status; 51. } 调用时只需两个参数便可以实现大文件的安全下载。download($url, $filename);