解决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 相关文章推荐
JAVA/JSP学习系列之七
Oct 09 PHP
几个学习PHP的网址
Nov 25 PHP
PHP 获取远程文件内容的函数代码
Mar 24 PHP
php结合表单实现一些简单功能的例子
Jun 04 PHP
PHP函数in_array()使用详解
Aug 20 PHP
用php来限制每个ip每天浏览页面数量的实现思路
Feb 24 PHP
Zend Framework生成验证码并实现验证码验证功能(附demo源码下载)
Mar 22 PHP
使用php完成常见的文件上传功能(推荐)
Jan 13 PHP
PHP实现防盗链的方法分析
Jul 25 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
Jun 17 PHP
php常用经典函数集锦【数组、字符串、栈、队列、排序等】
Aug 23 PHP
php进程(线程)通信基础之System V共享内存简单实例分析
Nov 09 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
火影忍者:三大瞳力之一的白眼,为什么没有写轮眼那么出色?
2020/03/02 日漫
简单的php中文转拼音的实现代码
2014/02/11 PHP
WordPress中获取所使用的模板的页面ID的简单方法
2015/12/31 PHP
thinkphp 验证码 的使用小结
2017/05/07 PHP
Javascript 入门基础学习
2010/03/10 Javascript
apycom出品的jQuery精美菜单破解方法
2011/02/18 Javascript
js中数组Array的一些常用方法总结
2013/08/12 Javascript
js的.innerHTML = &quot;&quot;IE9下显示有错误的解决方法
2013/09/16 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
JS获取iframe中marginHeight和marginWidth属性的方法
2015/04/01 Javascript
jQuery实现每隔几条元素增加1条线的方法
2016/06/27 Javascript
jquery实现input框获取焦点的简单实例
2017/01/26 Javascript
JS如何判断浏览器类型和详细区分IE各版本浏览器
2017/03/04 Javascript
Bootstrap栅格系统简单实现代码
2017/03/06 Javascript
jQuery实现可兼容IE6的滚动监听功能
2017/09/20 jQuery
Vue.js实现分页查询功能
2020/11/15 Javascript
小程序云开发实现数据库异步操作同步化
2019/05/18 Javascript
jQuery 筛选器简单操作示例
2019/10/02 jQuery
VSCode搭建React Native环境
2020/05/07 Javascript
Python动态加载模块的3种方法
2014/11/22 Python
Windows系统配置python脚本开机启动的3种方法分享
2015/03/10 Python
python操作ssh实现服务器日志下载的方法
2015/06/03 Python
Python实现简单生成验证码功能【基于random模块】
2018/02/10 Python
解决Python selenium get页面很慢时的问题
2019/01/30 Python
详解用python自制微信机器人,定时发送天气预报
2019/03/25 Python
python简单实现最大似然估计&amp;scipy库的使用详解
2020/04/15 Python
加拿大女包品牌:Matt & Nat
2017/05/12 全球购物
微博营销计划书
2014/01/10 职场文书
事业单位公务员的职业生涯规划
2014/01/15 职场文书
计算机科学与技术专业求职信
2014/09/03 职场文书
表扬通报怎么写
2015/01/16 职场文书
党员个人年度总结
2015/02/14 职场文书
团结友爱主题班会
2015/08/13 职场文书
安全学习心得体会范文
2016/01/18 职场文书
小学数学新课改心得体会
2016/01/22 职场文书
委托书范本格式
2019/04/18 职场文书