Home  >  Article  >  Backend Development  >  PHP implementation code for safely downloading large files

PHP implementation code for safely downloading large files

WBOY
WBOYOriginal
2016-07-25 08:58:51775browse
  1. /**
  2. * Safe download of general files
  3. * edit bbs.it-home.org
  4. */
  5. $durl = 'file/phpcms2008_o2abf32efj883c91a.iso';
  6. $filename = 'phpcms2008_o2abf32efj883c91a.iso';
  7. $file = @fopen ($durl, 'r');
  8. header("Content-Type: application/octet-stream"); ​​
  9. header("Accept-Ranges: bytes");
  10. header("Accept-Length: ".filesize($durl));
  11. header("Content-Disposition: attachment; filename=".$filename);
  12. echo fread($file,filesize($durl));
  13. fclose($file);
  14. ?>
Copy code

When the above code encounters a large file that exceeds the maximum memory value configured in php.ini, the server will occupy a lot of CPU resources and the file cannot be downloaded normally, and only files of dozens of Kb can be downloaded. This can be solved with the following code:

  1. /**
  2. * Implementation code for safe downloading of large files
  3. * edit bbs.it-home.org
  4. */
  5. function download($url, $filename) {
  6. // Get the file size, prevent files exceeding 2G, use sprintf to read
  7. $filesize = sprintf ( "%u", filesize ( $url ) );
  8. if (! $filesize) {
  9. return;
  10. }
  11. header ( "Content-type:application/octet-streamn" ); //application/octet- stream
  12. header ( "Content-type:unknown/unknown;" );
  13. header ( "Content-disposition: attachment; filename="" . $filename . """ );
  14. header ( 'Content-transfer-encoding: binary ' );
  15. if ($range = getenv ( 'HTTP_RANGE' )) { // When there is an offset, use the breakpoint resume header of 206
  16. $range = explode ( '=', $range );
  17. $range = $range [1];
  18. header ( "HTTP/1.1 206 Partial Content" );
  19. header ( "Date: " . gmdate ( "D, d M Y H:i:s" ) . " GMT" );
  20. header ( "Last-Modified: " . gmdate ( "D, d M Y H:i:s", filemtime ( $url ) ) . " GMT" );
  21. header ( "Accept-Ranges: bytes" );
  22. header ( "Content-Length:" . ($filesize - $range) );
  23. header ( "Content-Range: bytes " . $range . ($filesize - 1) . "/" . $filesize );
  24. header ( "Connection : close" . "nn" );
  25. } else {
  26. header ( "Content-Length:" . $filesize . "nn" );
  27. $range = 0;
  28. }
  29. loadFile ( $url );
  30. }
  31. function loadFile($filename, $retbytes = true) {
  32. $buffer = '';
  33. $cnt = 0;
  34. $handle = fopen ( $filename, 'rb' );
  35. if ($handle === false) {
  36. return false;
  37. }
  38. while ( ! feof ( $handle ) ) {
  39. $buffer = fread ( $handle, 1024 * 1024 );
  40. echo $buffer;
  41. ob_flush ();
  42. flush ();
  43. if ($ retbytes) {
  44. $cnt += strlen ( $buffer );
  45. }
  46. }
  47. $status = fclose ( $handle );
  48. if ($retbytes && $status) {
  49. return $cnt; // return num. bytes delivered like readfile() does.
  50. }
  51. return $status;
  52. }
  53. ?>
Copy code

Call example:

  1. //Safe download of large files
  2. download($url, $filename);
Copy code


Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn