解决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 相关文章推荐
五款常用mysql slow log分析工具的比较分析
May 22 PHP
PHP异步调用socket实现代码
Jan 12 PHP
smarty巧妙处理iframe中内容页的代码
Mar 07 PHP
php excel reader读取excel内容存入数据库实现代码
Dec 06 PHP
用mysql_fetch_array()获取当前行数据的方法详解
Jun 05 PHP
Dwz与thinkphp整合下的数据导出到Excel实例
Dec 04 PHP
php静态文件生成类实例分析
Jan 03 PHP
php实现的用户查询类实例
Jun 18 PHP
php实现的网页版剪刀石头布游戏示例
Nov 25 PHP
php中的单引号、双引号和转义字符详解
Feb 16 PHP
PHP实现Unicode编码相互转换的方法示例
Nov 17 PHP
php 提交表单 关闭layer弹窗iframe的实例讲解
Aug 20 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
微信公众号开发之微信公共平台消息回复类实例
2014/11/14 PHP
php接口数据加密、解密、验证签名
2015/03/12 PHP
在Linux系统下一键重新安装WordPress的脚本示例
2015/06/30 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
2016/10/17 PHP
Codeigniter里的无刷新上传的实现代码
2019/04/14 PHP
JS 密码强度验证(兼容IE,火狐,谷歌)
2010/03/15 Javascript
YUI的Tab切换实现代码
2010/04/11 Javascript
jquery 选择器引擎sizzle浅析
2013/02/06 Javascript
跟我学Nodejs(一)--- Node.js简介及安装开发环境
2014/05/20 NodeJs
js实现window.open不被拦截的解决方法汇总
2014/10/30 Javascript
jQuery中$.extend()用法实例
2015/06/24 Javascript
javascript实现添加附件功能的方法
2015/11/18 Javascript
jQuery插件编写步骤详解
2016/06/03 Javascript
通过npm引用的vue组件使用详解
2017/03/02 Javascript
JavaScript中清空数组的三种方式
2017/03/22 Javascript
浅谈gulp创建完整的项目流程
2017/12/20 Javascript
js实现控制文件拖拽并获取拖拽内容功能
2018/02/17 Javascript
小程序实现上传视频功能
2020/08/18 Javascript
js实现弹幕墙效果
2020/12/10 Javascript
[00:34]拔城逐梦,热血永恒!2020(秋)完美世界城市挑战赛报名开启
2020/10/09 DOTA
Python开发SQLite3数据库相关操作详解【连接,查询,插入,更新,删除,关闭等】
2017/07/27 Python
使用Python脚本从文件读取数据代码实例
2020/01/19 Python
使用OpenCV校准鱼眼镜头的方法
2020/11/26 Python
详解FireFox下Canvas使用图像合成绘制SVG的Bug
2019/07/10 HTML / CSS
波兰香水和化妆品购物网站:Notino.pl
2017/11/07 全球购物
日本乐天德国站:Rakuten.de
2019/05/16 全球购物
美国医生配方营养补充剂供应商:Healthy Directions
2019/07/10 全球购物
印度在线购物网站:Paytmmall
2019/07/24 全球购物
关于Java finally的面试题
2016/04/27 面试题
优秀员工表扬信
2014/01/17 职场文书
学习党的群众路线教育实践活动心得体会
2014/03/01 职场文书
导师就业推荐信范文
2014/05/22 职场文书
英语辞职信范文
2015/02/28 职场文书
求职自我评价怎么写
2015/03/09 职场文书
征求意见函
2015/06/05 职场文书
确保减税降费落地生根,用实实在在措施
2019/07/19 职场文书