解决PHP超大文件下载,断点续传下载的方法详解


Posted in PHP onJune 06, 2013

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

<?php 
$sourceFile = "1.tmp"; //要下载的临时文件名 
$outFile = "用户订单.xls"; //下载保存到客户端的文件名 
$file_extension = strtolower(substr(strrchr($sourceFile, "."), 1)); //获取文件扩展名 
//echo $sourceFile; 
if (!ereg("[tmp|txt|rar|pdf|doc]", $file_extension))exit ("非法资源下载"); 
//检测文件是否存在 
if (!is_file($sourceFile)) { 
die("<b>404 File not found!</b>"); 
} 
$len = filesize($sourceFile); //获取文件大小 
$filename = basename($sourceFile); //获取文件名字 
$outFile_extension = strtolower(substr(strrchr($outFile, "."), 1)); //获取文件扩展名 
//根据扩展名 指出输出浏览器格式 
switch ($outFile_extension) { 
case "exe" : 
$ctype = "application/octet-stream"; 
break; 
case "zip" : 
$ctype = "application/zip"; 
break; 
case "mp3" : 
$ctype = "audio/mpeg"; 
break; 
case "mpg" : 
$ctype = "video/mpeg"; 
break; 
case "avi" : 
$ctype = "video/x-msvideo"; 
break; 
default : 
$ctype = "application/force-download"; 
} 
//Begin writing headers 
header("Cache-Control:"); 
header("Cache-Control: public"); 
//设置输出浏览器格式 
header("Content-Type: $ctype"); 
header("Content-Disposition: attachment; filename=" . $outFile); 
header("Accept-Ranges: bytes"); 
$size = filesize($sourceFile); 
//如果有$_SERVER['HTTP_RANGE']参数 
if (isset ($_SERVER['HTTP_RANGE'])) { 
/*Range头域 Range头域可以请求实体的一个或者多个子范围。 
例如, 
表示头500个字节:bytes=0-499 
表示第二个500字节:bytes=500-999 
表示最后500个字节:bytes=-500 
表示500字节以后的范围:bytes=500- 
第一个和最后一个字节:bytes=0-0,-1 
同时指定几个范围:bytes=500-600,601-999 
但是服务器可以忽略此请求头,如果无条件GET包含Range请求头,响应会以状态码206(PartialContent)返回而不是以200 (OK)。 
*/ 
// 断点后再次连接 $_SERVER['HTTP_RANGE'] 的值 bytes=4390912- 
list ($a, $range) = explode("=", $_SERVER['HTTP_RANGE']); 
//if yes, download missing part 
str_replace($range, "-", $range); //这句干什么的呢。。。。 
$size2 = $size -1; //文件总字节数 
$new_length = $size2 - $range; //获取下次下载的长度 
header("HTTP/1.1 206 Partial Content"); 
header("Content-Length: $new_length"); //输入总长 
header("Content-Range: bytes $range$size2/$size"); //Content-Range: bytes 4908618-4988927/4988928 95%的时候 
} else { 
//第一次连接 
$size2 = $size -1; 
header("Content-Range: bytes 0-$size2/$size"); //Content-Range: bytes 0-4988927/4988928 
header("Content-Length: " . $size); //输出总长 
} 
//打开文件 
$fp = fopen("$sourceFile", "rb"); 
//设置指针位置 
fseek($fp, $range); 
//虚幻输出 
while (!feof($fp)) { 
//设置文件最长执行时间 
set_time_limit(0); 
print (fread($fp, 1024 * 8)); //输出文件 
flush(); //输出缓冲 
ob_flush(); 
} 
fclose($fp); 
exit ();

PHP 相关文章推荐
解决phpmyadmin中文乱码问题。。。
Jan 18 PHP
在同一窗体中使用PHP来处理多个提交任务
May 08 PHP
php长字符串定义方法
Jul 12 PHP
PHP 类相关函数的使用详解
May 10 PHP
基于Discuz security.inc.php代码的深入分析
Jun 03 PHP
ThinkPHP3.1新特性之Action参数绑定
Jun 19 PHP
php使用substr()和strpos()联合查找字符串中某一特定字符的方法
May 12 PHP
PHP如何使用Memcached
Apr 05 PHP
smarty的section嵌套循环用法示例
May 28 PHP
在Mac OS下搭建LNMP开发环境的步骤详解
Mar 10 PHP
浅谈PHP的排列组合(如输入a,b,c 输出他们的全部组合)
Mar 14 PHP
PHP接口类(interface)的定义、特点和应用示例
May 18 PHP
探讨PHP函数ip2long转换IP时数值太大产生负数的解决方法
Jun 06 #PHP
php IP转换整形(ip2long)的详解
Jun 06 #PHP
php全局变量和类配合使用深刻理解
Jun 05 #PHP
php数组声明、遍历、数组全局变量使用小结
Jun 05 #PHP
PHP Global变量定义当前页面的全局变量实现探讨
Jun 05 #PHP
PHP 常用数组内部函数(Array Functions)介绍
Jun 05 #PHP
php将gd生成的图片缓存到memcache的小例子
Jun 05 #PHP
You might like
php 截取GBK文档某个位置开始的n个字符方法
2017/03/08 PHP
Laravel使用支付宝进行支付的示例代码
2017/08/16 PHP
基于jQuery图片平滑连续滚动插件
2009/04/27 Javascript
jQuery Tips 为AJAX回调函数传递额外参数的方法
2010/12/28 Javascript
jQuery中removeClass()方法用法实例
2015/01/05 Javascript
JavaScript实现获取某个元素相邻兄弟节点的prev与next方法
2016/01/25 Javascript
AngularJS框架中的双向数据绑定机制详解【减少需要重复的开发代码量】
2017/01/19 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
2017/03/14 Javascript
利用nginx + node在阿里云部署https的步骤详解
2017/12/19 Javascript
解决koa2 ctx.render is not a function报错问题
2018/08/07 Javascript
koa router 多文件引入的方法示例
2019/05/22 Javascript
python通过pil模块获得图片exif信息的方法
2015/03/16 Python
使用python实现rsa算法代码
2016/02/17 Python
Python 数据结构之队列的实现
2017/01/22 Python
python下解压缩zip文件并删除文件的实例
2018/04/24 Python
python 中字典嵌套列表的方法
2018/07/03 Python
Python实现京东秒杀功能代码
2019/05/16 Python
Win10环境python3.7安装dlib模块趟过的坑
2019/08/01 Python
python实现超市商品销售管理系统
2019/11/22 Python
解决django接口无法通过ip进行访问的问题
2020/03/27 Python
挪威太阳镜和眼镜网上商城:SmartBuyGlasses挪威
2016/08/20 全球购物
美国电视购物HSN官网:HSN
2016/09/07 全球购物
澳大利亚领先的宠物用品商店:VetSupply
2017/09/08 全球购物
西班牙多品牌鞋店连锁店:Krack
2018/11/30 全球购物
伦敦香水公司:The London Perfume Company
2019/11/13 全球购物
C有"按引用传递"吗
2016/09/06 面试题
行政内勤岗位职责
2014/04/07 职场文书
临床医学专业求职信
2014/08/08 职场文书
个人主要事迹材料
2014/08/26 职场文书
行政专员岗位职责范本
2014/08/26 职场文书
五好家庭申报材料
2014/12/20 职场文书
大学军训决心书
2015/02/05 职场文书
经营场所使用证明
2015/06/19 职场文书
穆斯林的葬礼读书笔记
2015/06/26 职场文书
2016三严三实专题教育活动心得体会
2016/01/06 职场文书
MySQL中int (10) 和 int (11) 的区别
2022/01/22 MySQL