专注于discuz,uchome,dedecms等各类PHP程序仿站(二次开发和模板制作)。

« »

PHP超大文件下载,断点续传下载

  最近公司导出订单信息的时候出现一个php内存溢出的问题,原因就是在于下载的时候读取生成的临时文件过大,PHP内存无法容纳,一开如是想到更改PHP内存限制,但是这个只是一个缓兵之计,于是想到了另外一个方法是把文件分次读取,并下载。

以下是源代码:

  1. <?php  
  2. $sourceFile = “1.tmp”//要下载的临时文件名  
  3.   
  4. $outFile = “用户订单.xls”//下载保存到客户端的文件名  
  5.   
  6. $file_extension = strtolower(substr(strrchr($sourceFile“.”), 1)); //获取文件扩展名  
  7. //echo $sourceFile;  
  8. if (!ereg(“[tmp|txt|rar|pdf|doc]“$file_extension))exit (“非法资源下载”);  
  9.   
  10. //检测文件是否存在  
  11. if (!is_file($sourceFile)) {  
  12.     die(“<b>404 File not found!</b>”);  
  13. }  
  14.   
  15. $len = filesize($sourceFile); //获取文件大小  
  16. $filename = basename($sourceFile); //获取文件名字  
  17. $outFile_extension = strtolower(substr(strrchr($outFile“.”), 1)); //获取文件扩展名  
  18.   
  19. //根据扩展名 指出输出浏览器格式  
  20. switch ($outFile_extension) {  
  21.     case “exe” :  
  22.         $ctype = “application/octet-stream”;  
  23.         break;  
  24.     case “zip” :  
  25.         $ctype = “application/zip”;  
  26.         break;  
  27.     case “mp3″ :  
  28.         $ctype = “audio/mpeg”;  
  29.         break;  
  30.     case “mpg” :  
  31.         $ctype = “video/mpeg”;  
  32.         break;  
  33.     case “avi” :  
  34.         $ctype = “video/x-msvideo”;  
  35.         break;  
  36.     default :  
  37.         $ctype = “application/force-download”;  
  38. }  
  39. //Begin writing headers  
  40. header(“Cache-Control:”);  
  41. header(“Cache-Control: public”);  
  42.   
  43. //设置输出浏览器格式  
  44. header(“Content-Type: $ctype”);  
  45. header(“Content-Disposition: attachment; filename=” . $outFile);  
  46. header(“Accept-Ranges: bytes”);  
  47.   
  48. $size = filesize($sourceFile);  
  49.   
  50. //如果有$_SERVER['HTTP_RANGE']参数  
  51. if (isset ($_SERVER['HTTP_RANGE'])) {  
  52.     /*Range头域   Range头域可以请求实体的一个或者多个子范围。  
  53.     例如,  
  54.     表示头500个字节:bytes=0-499  
  55.     表示第二个500字节:bytes=500-999  
  56.     表示最后500个字节:bytes=-500  
  57.     表示500字节以后的范围:bytes=500-     
  58.     第一个和最后一个字节:bytes=0-0,-1     
  59.     同时指定几个范围:bytes=500-600,601-999     
  60.     但是服务器以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。  
  61.     */  
  62.     // 断点后再次连接 $_SERVER['HTTP_RANGE'] 的值 bytes=4390912-  
  63.     list ($a$range) = explode(“=”$_SERVER['HTTP_RANGE']);  
  64.     //if yes, download missing part  
  65.     str_replace($range“-”$range); //这句干什么的呢。。。。  
  66.     $size2 = $size -1; //文件总字节数  
  67.     $new_length = $size2 - $range//获取下次下载的长度  
  68.     header(“HTTP/1.1 206 Partial Content”);  
  69.     header(“Content-Length: $new_length”); //输入总长  
  70.     header(“Content-Range: bytes $range$size2/$size”); //Content-Range: bytes 4908618-4988927/4988928   95%的时候  
  71. else {  
  72.     //第一次连接  
  73.     $size2 = $size -1;  
  74.     header(“Content-Range: bytes 0-$size2/$size”); //Content-Range: bytes 0-4988927/4988928  
  75.     header(“Content-Length: ” . $size); //输出总长  
  76. }  
  77. //打开文件  
  78. $fp = fopen(“$sourceFile”“rb”);  
  79. //设置指针位置  
  80. fseek($fp$range);  
  81. //虚幻输出  
  82. while (!feof($fp)) {  
  83.     //设置文件最长执行时间  
  84.     set_time_limit(0);  
  85.     print (fread($fp, 1024 * 8)); //输出文件  
  86.     flush(); //输出缓冲  
  87.     ob_flush();  
  88. }  
  89. fclose($fp);  
  90. exit ();  
  91. ?>  

 

PHP超大文件下载,断点续传下载 – 大友博客-PHP爱好者.

原创文章如转载,请注明:转载自火跃工作室
本文网址:http://www.huoyue.org/php-big-file-down

日志信息 »

该日志于2012-02-16 21:07由 火跃 发表在PHP+mysql分类下, 你可以发表评论。除了可以将这个日志以保留源地址及作者的情况下引用到你的网站或博客,还可以通过RSS 2.0订阅这个日志的所有评论。

相关日志 »

1条评论

  1. 武林之人 说到:

    哈哈,不错不错,总算找到了!

发表评论 »