解决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 相关文章推荐
Win9x/ME下Apache+PHP安装配置
Oct 09 PHP
动态新闻发布的实现及其技巧
Oct 09 PHP
模拟SQLSERVER的两个函数:dateadd(),datediff()
Oct 09 PHP
新手学PHP之数据库操作详解及乱码解决!
Jan 02 PHP
php ftp文件上传函数(基础版)
Jun 03 PHP
PHP中new static() 和 new self() 的区别介绍
Jan 09 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
Jul 03 PHP
将PHP程序中返回的JSON格式数据用gzip压缩输出的方法
Mar 03 PHP
关于php几种字符串连接的效率比较(详解)
Feb 22 PHP
laravel学习笔记之模型事件的几种用法示例
Aug 15 PHP
PHP的cookie与session原理及用法详解
Sep 27 PHP
laravel框架数据库操作、查询构建器、Eloquent ORM操作实例分析
Dec 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
PHP中的str_repeat函数在JavaScript中的实现
2013/09/16 PHP
PHP常用函数总结(180多个)
2016/12/25 PHP
购物车实现的几种方式优缺点对比
2018/05/02 PHP
php微信开发之音乐回复功能
2018/06/14 PHP
重写javascript中window.confirm的行为
2012/10/21 Javascript
解析使用js判断只能输入数字、字母等验证的方法(总结)
2013/05/14 Javascript
js获取url中的参数且参数为中文时通过js解码
2014/03/19 Javascript
轻量级的原生js日历插件calendar.js使用指南
2015/04/28 Javascript
js带缩略图的图片轮播效果代码分享
2015/09/14 Javascript
利用jQuery实现漂亮的圆形进度条倒计时插件
2015/09/30 Javascript
javascript瀑布流式图片懒加载实例
2020/06/28 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
原生js和css实现图片轮播效果
2017/02/07 Javascript
JS监控关闭浏览器操作的实例详解
2017/09/12 Javascript
nodejs简单读写excel内容的方法示例
2018/03/16 NodeJs
解决vue的变量在settimeout内部效果失效的问题
2018/08/30 Javascript
vue-cli 3.x配置跨域代理的实现方法
2019/04/12 Javascript
layui表格 列自动适应大小失效的解决方法
2019/09/06 Javascript
JS实现页面数据懒加载
2020/02/13 Javascript
Javascript 模拟mvc实现点餐程序案例详解
2020/12/24 Javascript
python写入中英文字符串到文件的方法
2015/05/06 Python
Python排序搜索基本算法之选择排序实例分析
2017/12/09 Python
python reverse反转部分数组的实例
2018/12/13 Python
Python制作exe文件简单流程
2019/01/24 Python
详解使用Python写一个向数据库填充数据的小工具(推荐)
2020/09/11 Python
python+selenium爬取微博热搜存入Mysql的实现方法
2021/01/27 Python
HTML5计时器小例子
2013/10/15 HTML / CSS
html5跨域通讯之postMessage的用法总结
2013/11/07 HTML / CSS
canvas裁剪clip()函数的具体使用
2018/03/01 HTML / CSS
英国独特的时尚和生活方式品牌:JOY
2018/03/17 全球购物
英国儿童设计师服装的领先零售商:Base
2019/03/17 全球购物
Kendra Scott官网:美国领先的时尚配饰品牌
2020/10/22 全球购物
网络工程师自荐书范文
2014/04/01 职场文书
应届毕业生求职信
2014/05/26 职场文书
计生办班子群众路线教育实践活动个人对照检查材料思想汇报
2014/10/04 职场文书
企业内部管理控制:采购授权审批制度范本
2020/01/19 职场文书