Home  >  Article  >  Backend Development  >  Useful php header download function

Useful php header download function

WBOY
WBOYOriginal
2016-07-25 08:54:40847browse
  1. /**

  2. * Send file
  3. *
  4. * @param string $fileName File name or path
  5. * @param string $fancyName Customized file name, if empty, use filename
  6. * @param boolean $forceDownload Whether to force download
  7. * @param integer $speedLimit speed limit, unit is bytes, 0 means no limit, does not support windows server
  8. * @param string $$contentType file type, the default is application/octet-stream
  9. *
  10. * @return boolean
  11. */
  12. function sendFile($fileName, $fancyName = '', $forceDownload = true, $speedLimit = 0, $contentType = '')
  13. {
  14. if (!is_readable($fileName))
  15. {
  16. header("HTTP/1.1 404 Not Found");
  17. return false;
  18. }
  19. $fileStat = stat($fileName);
  20. $lastModified = $fileStat['mtime'];

  21. $md5 = md5($fileStat['mtime'] .'='. $fileStat['ino'] .'='. $fileStat['size']);

  22. $etag = '"' . $md5 . '-' . crc32($md5) . '"';
  23. header('Last-Modified: ' . gmdate("D, d M Y H:i:s", $lastModified) . ' GMT');
  24. header("ETag: $etag");

  25. if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) >= $lastModified)

  26. {
  27. header("HTTP/1.1 304 Not Modified");
  28. return true;
  29. }
  30. if (isset($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) && strtotime($_SERVER['HTTP_IF_UNMODIFIED_SINCE']) < $lastModified)
  31. {
  32. header("HTTP/1.1 304 Not Modified");
  33. return true;
  34. }
  35. if (isset($_SERVER['HTTP_IF_NONE_MATCH']) && $_SERVER['HTTP_IF_NONE_MATCH'] == $etag)
  36. {
  37. header("HTTP/1.1 304 Not Modified");
  38. return true;
  39. }
  40. if ($fancyName == '')
  41. {
  42. $fancyName = basename($fileName);
  43. }

  44. if ($contentType == '')

  45. {
  46. $contentType = 'application/octet-stream';
  47. }
  48. $fileSize = $fileStat['size'];

  49. $contentLength = $fileSize;

  50. $isPartial = false;
  51. if (isset($_SERVER['HTTP_RANGE']))
  52. {
  53. if (preg_match('/^bytes=(d*)-(d*)$/', $_SERVER['HTTP_RANGE'], $matches))
  54. {
  55. $startPos = $matches[1];
  56. $endPos = $matches[2];
  57. if ($startPos == '' && $endPos == '')
  58. {
  59. return false;
  60. }

  61. if ($startPos == '')

  62. {
  63. $startPos = $fileSize - $endPos;
  64. $endPos = $fileSize - 1;
  65. }
  66. else if ($endPos == '')
  67. {
  68. $endPos = $fileSize - 1;
  69. }
  70. $startPos = $startPos < 0 ? 0 : $startPos;
  71. $endPos = $endPos > $fileSize - 1 ? $fileSize - 1 : $endPos;
  72. $length = $endPos - $startPos + 1;
  73. if ($length < 0)
  74. {
  75. return false;
  76. }
  77. $contentLength = $length;
  78. $isPartial = true;
  79. }
  80. }

  81. // send headers

  82. if ($isPartial)
  83. {
  84. header('HTTP/1.1 206 Partial Content');
  85. header("Content-Range: bytes $startPos-$endPos/$fileSize");

  86. }

  87. else
  88. {
  89. header("HTTP/1.1 200 OK");
  90. $startPos = 0;
  91. $endPos = $contentLength - 1;
  92. }
  93. header('Pragma: cache');
  94. header('Cache-Control: public, must-revalidate, max-age=0');
  95. header('Accept-Ranges: bytes');
  96. header('Content-type: ' . $contentType);
  97. header('Content-Length: ' . $contentLength);

  98. if ($forceDownload)

  99. {
  100. header('Content-Disposition: attachment; filename="' . rawurlencode($fancyName). '"');//汉字自动转为URL编码
  101. header('Content-Disposition: attachment; filename="' . $fancyName. '"');
  102. }
  103. header("Content-Transfer-Encoding: binary");
  104. // header函数实现文件下载

  105. $bufferSize = 2048;

  106. if ($speedLimit != 0)
  107. {
  108. $packetTime = floor($bufferSize * 1000000 / $speedLimit);
  109. }
  110. $bytesSent = 0;
  111. $fp = fopen($fileName, "rb");
  112. fseek($fp, $startPos);
  113. //fpassthru($fp);

  114. while ($bytesSent < $contentLength && !feof($fp) && connection_status() == 0 )

  115. {
  116. if ($speedLimit != 0)
  117. {
  118. list($usec, $sec) = explode(" ", microtime());
  119. $outputTimeStart = ((float)$usec + (float)$sec);
  120. } // bbs.it-home.org
  121. $readBufferSize = $contentLength - $bytesSent < $bufferSize ? $contentLength - $bytesSent : $bufferSize;
  122. $buffer = fread($fp, $readBufferSize);
  123. echo $buffer;
  124. ob_flush();
  125. flush();
  126. $bytesSent += $readBufferSize;

  127. if ($speedLimit != 0)

  128. {
  129. list($usec, $sec) = explode(" ", microtime());
  130. $outputTimeEnd = ((float)$usec + (float)$sec);

  131. $useTime = ((float) $outputTimeEnd - (float) $outputTimeStart) * 1000000;

  132. $sleepTime = round($packetTime - $useTime);
  133. if ($sleepTime > 0)
  134. {
  135. usleep($sleepTime);
  136. }
  137. }
  138. }
  139. return true;
  140. }
  141. ?>

复制代码


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