php实现大文件断点续传下载实例代码


Posted in PHP onOctober 01, 2019

php实现大文件断点续传下载实例,看完你就知道超过100M以上的大文件如何断点传输了,这个功能还是比较经典实用的,毕竟大文件上传功能经常用得到。

php实现大文件断点续传下载实例代码

require_once('download.class.php'); 
date_default_timezone_set('Asia/Shanghai'); 
error_reporting(E_STRICT); 
function errorHandler($errno, $errstr, $errfile, $errline) { 
 echo '<p>error:', $errstr, '</p>'; 
 exit(); 
} 
set_error_handler('errorHandler'); 
define('IS_DEBUG', true); 
$filePath = 'test.zip'; 
$mimeType = 'audio/x-matroska'; 
$range = isset($_SERVER['HTTP_RANGE']) ? $_SERVER['HTTP_RANGE'] : null; 
if (IS_DEBUG) { 
// $range = "bytes=1000-1999\n2000"; 
// $range = "bytes=1000-1999,2000"; 
// $range = "bytes=1000-1999,-2000"; 
// $range = "bytes=1000-1999,2000-2999"; 
} 
set_time_limit(0); 
$transfer = new Transfer($filePath, $mimeType, $range); 
if (IS_DEBUG) { 
 $transfer->setIsLog(true); 
} 
$transfer->send();

download.class.php

/** 
 * 文件传输,支持断点续传。 
 * 2g以上超大文件也有效 
 * @author MoXie 
 */ 
class Transfer { 
 /** 
  * 缓冲单元 
  */ 
 const BUFF_SIZE = 5120; // 1024 * 5 
 /** 
  * 文件地址 
  * @var <String> 
  */ 
 private $filePath; 
 /** 
  * 文件大小 
  * @var <String> Php超大数字 字符串形式描述 
  */ 
 private $fileSize; 
 /** 
  * 文件类型 
  * @var <String> 
  */ 
 private $mimeType; 
 /** 
  * 请求区域(范围) 
  * @var <String> 
  */ 
 private $range; 
 /** 
  * 是否写入日志 
  * @var <Boolean> 
  */ 
 private $isLog = false; 
 /** 
  * 
  * @param <String> $filePath 文件路径 
  * @param <String> $mimeType 文件类型 
  * @param <String> $range 请求区域(范围) 
  */ 
 function __construct($filePath, $mimeType = null, $range = null) { 
  $this->filePath = $filePath; 
  $this->fileSize = sprintf('%u', filesize($filePath)); 
  $this->mimeType = ($mimeType != null) ? $mimeType : "application/octet-stream"; // bin 
  $this->range = trim($range); 
 } 
 /** 
  * 获取文件区域 
  * @return <Map> {'start':long,'end':long} or null 
  */ 
 private function getRange() { 
  /** 
   * Range: bytes=-128 
   * Range: bytes=-128 
   * Range: bytes=28-175,382-399,510-541,644-744,977-980 
   * Range: bytes=28-175\n380 
   * type 1 
   * RANGE: bytes=1000-9999 
   * RANGE: bytes=2000-9999 
   * type 2 
   * RANGE: bytes=1000-1999 
   * RANGE: bytes=2000-2999 
   * RANGE: bytes=3000-3999 
   */ 
  if (!empty($this->range)) { 
   $range = preg_replace('/[\s|,].*/', '', $this->range); 
   $range = explode('-', substr($range, 6)); 
   if (count($range) < 2) { 
    $range[1] = $this->fileSize; // Range: bytes=-100 
   } 
   $range = array_combine(array('start', 'end'), $range); 
   if (empty($range['start'])) { 
    $range['start'] = 0; 
   } 
   if (!isset($range['end']) || empty($range['end'])) { 
    $range['end'] = $this->fileSize; 
   } 
   return $range; 
  } 
  return null; 
 } 
 /** 
  * 向客户端发送文件 
  */ 
 public function send() { 
  $fileHande = fopen($this->filePath, 'rb'); 
  if ($fileHande) { 
   // setting 
   ob_end_clean(); // clean cache 
   ob_start(); 
   ini_set('output_buffering', 'Off'); 
   ini_set('zlib.output_compression', 'Off'); 
   $magicQuotes = get_magic_quotes_gpc(); 
//   set_magic_quotes_runtime(0); 
   // init 
   $lastModified = gmdate('D, d M Y H:i:s', filemtime($this->filePath)) . ' GMT'; 
   $etag = sprintf('w/"%s:%s"', md5($lastModified), $this->fileSize); 
   $ranges = $this->getRange(); 
   // headers 
   header(sprintf('Last-Modified: %s', $lastModified)); 
   header(sprintf('ETag: %s', $etag)); 
   header(sprintf('Content-Type: %s', $this->mimeType)); 
   $disposition = 'attachment'; 
   if (strpos($this->mimeType, 'image/') !== FALSE) { 
    $disposition = 'inline'; 
   } 
   header(sprintf('Content-Disposition: %s; filename="%s"', $disposition, basename($this->filePath))); 
   if ($ranges != null) { 
    if ($this->isLog) { 
     $this->log(json_encode($ranges) . ' ' . $_SERVER['HTTP_RANGE']); 
    } 
    header('HTTP/1.1 206 Partial Content'); 
    header('Accept-Ranges: bytes'); 
    header(sprintf('Content-Length: %u', $ranges['end'] - $ranges['start'])); 
    header(sprintf('Content-Range: bytes %s-%s/%s', $ranges['start'], $ranges['end'], $this->fileSize)); 
    // 
    fseek($fileHande, sprintf('%u', $ranges['start'])); 
   } else { 
    header("HTTP/1.1 200 OK"); 
    header(sprintf('Content-Length: %s', $this->fileSize)); 
   } 
   // read file 
   $lastSize = 0; 
   while (!feof($fileHande) && !connection_aborted()) { 
    $lastSize = sprintf("%u", bcsub($this->fileSize, sprintf("%u", ftell($fileHande)))); 
    if (bccomp($lastSize, self::BUFF_SIZE) > 0) { 
     $lastSize = self::BUFF_SIZE; 
    } 
    echo fread($fileHande, $lastSize); 
    ob_flush(); 
    flush(); 
   } 
   set_magic_quotes_runtime($magicQuotes); 
   ob_end_flush(); 
  } 
  if ($fileHande != null) { 
   fclose($fileHande); 
  } 
 } 
 /** 
  * 设置记录 
  * @param <Boolean> $isLog 是否记录 
  */ 
 public function setIsLog($isLog = true) { 
  $this->isLog = $isLog; 
 } 
 /** 
  * 记录 
  * @param <String> $msg 记录信息 
  */ 
 private function log($msg) { 
  try { 
   $handle = fopen('transfer_log.txt', 'a'); 
   fwrite($handle, sprintf('%s : %s' . PHP_EOL, date('Y-m-d H:i:s'), $msg)); 
   fclose($handle); 
  } catch (Exception $e) { 
   // null; 
  } 
 } 
}

总结

以上所述是小编给大家介绍的php实现大文件断点续传下载实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

PHP 相关文章推荐
优化NFR之一 --MSSQL Hello Buffer Overflow
Oct 09 PHP
PHP中HTTP方式下的Gzip压缩传输方法举偶
Feb 15 PHP
用PHP写的基于Memcache的Queue实现代码
Nov 27 PHP
无需重新编译php加入ftp扩展的解决方法
Feb 07 PHP
Javascript与PHP验证用户输入URL地址是否正确
Oct 09 PHP
PHP中抽象类和抽象方法概念与用法分析
May 24 PHP
php设计模式之单例模式代码
Jun 11 PHP
PHP实现权限管理功能示例
Sep 22 PHP
php和vue配合使用技巧和方法
May 09 PHP
PHP中Session ID的实现原理实例分析
Aug 17 PHP
laravel model 两表联查示例
Oct 24 PHP
PHP读取文件,解决中文乱码UTF-8的方法分析
Jan 22 PHP
使用composer安装使用thinkphp6.0框架问题【视频教程】
Oct 01 #PHP
基于Laravel-admin 后台的自定义页面用法详解
Sep 30 #PHP
Laravel-admin之修改操作日志的方法
Sep 30 #PHP
laravel 字段格式化 modle 字段类型转换方法
Sep 30 #PHP
laravel-admin解决表单select联动时,编辑默认没选上的问题
Sep 30 #PHP
laravel-admin的图片删除实例
Sep 30 #PHP
laravel-admin的多级联动方法
Sep 30 #PHP
You might like
PHP用mysql数据库存储session的代码
2010/03/05 PHP
PHP实现读取一个1G的文件大小
2013/08/24 PHP
php检测文件编码的方法示例
2014/04/25 PHP
PHP 数组黑名单/白名单实例代码详解
2019/06/04 PHP
别了 JavaScript中的isXX系列
2012/08/01 Javascript
商城常用滚动的焦点图效果代码简单实用
2013/03/28 Javascript
JS中类或对象的定义说明
2014/03/10 Javascript
Jquery焦点图实例代码
2014/11/25 Javascript
JavaScript拖拽、碰撞、重力及弹性运动实例分析
2016/01/08 Javascript
jQuery+canvas实现的球体平抛及颜色动态变换效果
2016/01/28 Javascript
AngularJS全局警告框实现方法示例
2017/05/18 Javascript
Angular实现下载安装包的功能代码分享
2017/09/05 Javascript
ubuntu编译nodejs所需的软件并安装
2017/09/12 NodeJs
Vue封装Swiper实现图片轮播效果
2018/02/06 Javascript
vue.js-div滚动条隐藏但有滚动效果的实现方法
2018/03/03 Javascript
详解SPA中前端路由基本原理与实现方式
2018/09/12 Javascript
vue 之 css module的使用方法
2018/12/04 Javascript
vue双向绑定及观察者模式详解
2019/03/19 Javascript
如何在VUE中使用vue-awesome-swiper
2021/01/04 Vue.js
[00:48]DOTA2国际邀请赛公开赛报名开始 扫码开启逐梦之旅
2018/06/06 DOTA
python通过装饰器检查函数参数数据类型的方法
2015/03/13 Python
用Python实现斐波那契(Fibonacci)函数
2016/03/25 Python
python正则表达式的使用
2017/06/12 Python
python中文编码与json中文输出问题详解
2018/08/24 Python
Python学习笔记之lambda表达式用法详解
2019/08/08 Python
python GUI库图形界面开发之PyQt5滑块条控件QSlider详细使用方法与实例
2020/02/28 Python
详解pandas apply 并行处理的几种方法
2021/02/24 Python
Shopee越南:东南亚与台湾电商平台
2019/02/03 全球购物
CAT鞋加拿大官网:CAT Footwear加拿大
2020/08/05 全球购物
工作表现评语
2014/01/19 职场文书
师德师风演讲稿
2014/05/05 职场文书
环保倡议书范文
2014/05/12 职场文书
党的群众路线教育实践活动个人对照检查材料
2014/09/22 职场文书
2014年项目经理工作总结
2014/11/24 职场文书
期中考试后的感想
2015/08/07 职场文书
Python如何使用循环结构和分支结构
2022/04/13 Python