Download.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. namespace Qii\Library;
  3. set_time_limit (0);
  4. ignore_user_abort(false);
  5. class Download
  6. {
  7. const VERSION = 1.0;
  8. //下载速率
  9. public $speed = 1000;
  10. public function __construct()
  11. {
  12. }
  13. /**
  14. * 以字符串的形式下载文件
  15. *
  16. * @param String $fileName 保存的文件名
  17. * @param String $string 下载的内容
  18. */
  19. public function downloadByString($fileName, $string)
  20. {
  21. header('Cache-Control: max-age=2592000');
  22. header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
  23. header('Cache-Control: no-store, no-cache, must-revalidate');
  24. header('Cache-Control: pre-check=0, post-check=0, max-age=0');
  25. header("Content-type: application/octet-stream");
  26. header("Accept-Length: ". sizeof($string));
  27. $fileName = toGBK(urlencode($fileName));
  28. header("Content-Disposition: attachment; filename=". $fileName);
  29. echo $string;
  30. }
  31. /**
  32. * 断点续传
  33. *
  34. * @param string $filePath 文件路径
  35. * @param string $fileName 下载后的文件名
  36. * @param string $mime 文件类型,如果是空的话就直接下载
  37. * @return bool
  38. */
  39. public function downResume($filePath, $fileName = '', $mime = '')
  40. {
  41. if (!file_exists($filePath)) {
  42. return false;
  43. }
  44. if ($fileName == '') {
  45. $fileName = basename($filePath);
  46. }
  47. $size = filesize($filePath);
  48. $size2 = $size - 1;
  49. $range = 0;
  50. if (isset($_SERVER['HTTP_RANGE']))
  51. {
  52. header('HTTP /1.1 206 Partial Content');
  53. $range = str_replace('=', '-', $_SERVER['HTTP_RANGE']);
  54. $range = explode('-', $range);
  55. $range = trim($range[1]);
  56. header('Content-Length:' . $size);
  57. header('Content-Range: bytes ' . $range . '-' . $size2 . '/' . $size);
  58. }
  59. else
  60. {
  61. header('Content-Length:' . $size);
  62. header('Content-Range: bytes 0-' . $size2 . '/' . $size);
  63. }
  64. header('Accenpt-Ranges: bytes');
  65. if ($mime != '' && $mime != 'unlink')
  66. {
  67. header("Content-type: {$mime}");
  68. }
  69. else
  70. {
  71. header("Content-type: application/octet-stream");
  72. }
  73. header("Cache-control: public");
  74. header("Pragma: public");
  75. $fileName = toGBK(urlencode($fileName));
  76. header('Content-Dispositon:attachment; filename=' . $fileName);
  77. $fp = fopen($filePath, 'rb+');
  78. fseek($fp, $range);
  79. while (!feof($fp))
  80. {
  81. set_time_limit(0);
  82. print(fread($fp, 1024));
  83. flush();
  84. ob_flush();
  85. }
  86. fclose($fp);
  87. }
  88. /**
  89. * 指定文件路径下载指定文件
  90. *
  91. * @param String $filePath 文件路径
  92. * @param String $fileName 文件名
  93. * @param String $mime 文件类型
  94. * @param String $view 下载/打开文件
  95. */
  96. public function download($filePath, $fileName = '', $mime = '', $view = 'download')
  97. {
  98. //转换文件路为GBK,避免无法访问中文文件
  99. $filePath = toGBK($filePath);
  100. if(!file_exists($filePath))
  101. {
  102. die('File '. $filePath .' does not exist.');
  103. }
  104. if($fileName == '')
  105. {
  106. $fileName = basename($filePath);
  107. }
  108. $file = fopen($filePath, "r"); // 打开文件
  109. // 输入文件标签
  110. header('Cache-Control: max-age=2592000');
  111. header('Last-Modified: '.gmdate('D, d M Y H:i:s') . ' GMT');
  112. header('Cache-Control: no-store, no-cache, must-revalidate');
  113. header('Cache-Control: pre-check=0, post-check=0, max-age=0');
  114. if($mime != '' && $mime != 'unlink')
  115. {
  116. header("Content-type: {$mime}");
  117. }
  118. else
  119. {
  120. header("Content-type: application/octet-stream");
  121. }
  122. header('Content-Encoding: none');
  123. header('Content-Transfer-Encoding: binary');
  124. header("Accept-Ranges: bytes");
  125. header("Accept-Length: ". filesize($filePath));
  126. $fileName = toGBK(urlencode($fileName));
  127. if($view == 'download')
  128. {
  129. header("Content-Disposition: attachment; filename=". $fileName);
  130. }
  131. else
  132. {
  133. header('Content-Disposition: inline;filename="'.$fileName.'"');
  134. }
  135. //输出固定长度的文件避免文件过大导致无法下载
  136. $chunk = 16384;
  137. $sleep = $this->speed ? floor(( $chunk / ($this->speed*1024))*1000000) : 0;
  138. do
  139. {
  140. $buf = fread($file, $chunk);
  141. echo $buf;
  142. ob_flush();
  143. flush();
  144. usleep($sleep);
  145. if(strlen($buf) == 0)
  146. {
  147. break;
  148. }
  149. }while(true);
  150. fclose($file);
  151. }
  152. }