解决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 相关文章推荐
PHP脚本的10个技巧(5)
Oct 09 PHP
一篇入门的php Class 文章
Apr 04 PHP
PHP多线程抓取网页实现代码
Jul 22 PHP
php将gd生成的图片缓存到memcache的小例子
Jun 05 PHP
php检测数组长度函数sizeof与count用法
Nov 17 PHP
php实现模拟post请求用法实例
Jul 11 PHP
Zend Framework分页类用法详解
Mar 22 PHP
Linux php 中文乱码的快速解决方法
May 13 PHP
PHP实现小偷程序实例
Oct 31 PHP
购物车实现的几种方式优缺点对比
May 02 PHP
PHP SESSION机制的理解与实例
Mar 22 PHP
php自动加载代码实例详解
Feb 26 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
5种PHP创建数组的实例代码分享
2014/01/17 PHP
php中stream(流)的用法
2014/03/25 PHP
浅谈COOKIE和SESSION区别
2015/07/19 PHP
Extjs学习笔记之八 继承和事件基础
2010/01/08 Javascript
JavaScript中匿名函数用法实例
2015/03/23 Javascript
使用jquery/js获取iframe父子级、同级获取元素的方法
2016/08/05 Javascript
jQuery用FormData实现文件上传的方法
2016/11/21 Javascript
微信小程序实现图片放大预览功能
2020/10/22 Javascript
jQuery模拟html下拉多选框的原生实现方法示例
2019/05/30 jQuery
js实现简单页面全屏
2019/09/17 Javascript
vue+element表格导出为Excel文件
2019/09/26 Javascript
uni-app 支持多端第三方地图定位的方法
2020/01/03 Javascript
js实现带有动画的返回顶部
2020/08/09 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
2020/09/01 Javascript
python获取本机mac地址和ip地址的方法
2015/04/29 Python
python爬取个性签名的方法
2018/06/17 Python
python3下载抖音视频的完整代码
2019/06/05 Python
python hash每次调用结果不同的原因
2019/11/21 Python
利用Tensorboard绘制网络识别准确率和loss曲线实例
2020/02/15 Python
如何教少儿学习Python编程
2020/07/10 Python
SpringBoot首页设置解析(推荐)
2021/02/11 Python
HTML5各种头部meta标签的功能(推荐)
2017/03/13 HTML / CSS
理肤泉俄罗斯官网:La Roche-Posay俄罗斯
2018/07/24 全球购物
英国信箱在线鲜花速递公司:Bloom & Wild
2019/03/10 全球购物
金智子午JAVA面试题
2015/09/04 面试题
软件测试有哪些?什么是配置项?
2012/02/12 面试题
机修工岗位职责
2013/11/24 职场文书
网吧收银员岗位职责
2013/12/14 职场文书
高三毕业生自我鉴定
2013/12/20 职场文书
创业计划书怎样才能打动风投
2014/01/01 职场文书
热爱祖国演讲稿
2014/05/04 职场文书
2015年酒店工作总结范文
2015/04/07 职场文书
幼儿园托班教育随笔
2015/08/14 职场文书
2016年度先进班组事迹材料
2016/03/01 职场文书
nginx如何将http访问的网站改成https访问
2021/03/31 Servers
mongodb数据库迁移变更的解决方案
2021/09/04 MongoDB