解决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 编写的 25个游戏脚本
May 11 PHP
DedeCMS dede_channeltype表字段注释
Apr 07 PHP
CodeIgniter中实现泛域名解析
Jul 19 PHP
递归实现php数组转xml的代码分享
May 14 PHP
深入浅析yii2-gii自定义模板的方法
Apr 26 PHP
php分页原理 分页代码 分页类制作教程
Sep 23 PHP
php中mkdir()函数的权限问题分析
Sep 24 PHP
详解PHP中的序列化、反序列化操作
Mar 21 PHP
PHP单例模式简单用法示例
Jun 23 PHP
PHP有序表查找之二分查找(折半查找)算法示例
Feb 09 PHP
PHP有序表查找之插值查找算法示例
Feb 10 PHP
PHP实现递归的三种方法
Jul 04 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在XP下IIS和Apache2服务器上的安装
2006/09/05 PHP
文章推荐系统(三)
2006/10/09 PHP
一个php作的文本留言本的例子(三)
2006/10/09 PHP
PHP 多维数组排序(usort,uasort)
2010/06/30 PHP
ThinkPHP实例化模型的四种方法概述
2014/08/22 PHP
PHP strtotime函数用法、实现原理和源码分析
2015/02/04 PHP
PHP的Yii框架中Model模型的学习教程
2016/03/29 PHP
[原创]smarty简单模板变量输出方法
2016/07/09 PHP
如何正确配置Nginx + PHP
2016/07/15 PHP
php出租房数据管理及搜索页面
2017/05/23 PHP
PHP session垃圾回收机制实例分析
2019/06/28 PHP
js的Boolean对象初始值示例
2014/03/04 Javascript
javascript跨浏览器的属性判断方法
2014/03/16 Javascript
jquery 构造函数在表单提交过程中修改数据
2015/05/25 Javascript
js获取页面引用的css样式表中的属性值方法(推荐)
2016/08/19 Javascript
JS实用的带停顿的逐行文本循环滚动效果实例
2016/11/23 Javascript
原生javascript实现图片放大镜效果
2017/01/18 Javascript
react-router JS 控制路由跳转实例
2017/06/15 Javascript
Node调用Java的示例代码
2017/09/20 Javascript
vue3.0 CLI - 2.4 - 新组件 Forms.vue 中学习表单
2018/09/14 Javascript
vue 中基于html5 drag drap的拖放效果案例分析
2018/11/01 Javascript
vue Treeselect下拉树只能选择第N级元素实现代码
2020/08/31 Javascript
如何处理Python3.4 使用pymssql 乱码问题
2016/01/08 Python
线程安全及Python中的GIL原理分析
2019/10/29 Python
从多个tfrecord文件中无限读取文件的例子
2020/02/17 Python
pycharm设置默认的UTF-8编码模式的方法详解
2020/06/01 Python
解决pytorch 数据类型报错的问题
2021/03/03 Python
详解利用canvas实现环形进度条的方法
2019/06/12 HTML / CSS
Giglio俄罗斯奢侈品购物网:男士、女士、儿童高级时装
2018/07/27 全球购物
工作睡觉检讨书
2014/02/25 职场文书
《果园机器人》教学反思
2014/04/13 职场文书
门前三包责任书
2014/04/15 职场文书
大学生工作自荐书
2014/06/16 职场文书
开展读书活动总结
2014/06/30 职场文书
成本会计实训报告
2014/11/05 职场文书
读《解忧杂货店》有感:请相信一切都是最好的安排
2019/11/07 职场文书