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

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

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实现大文件断点续传下载实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

(0)

相关推荐

  • php实现的支持断点续传的文件下载类

    本文实例讲述了php实现的支持断点续传的文件下载类及其用法,是非常实用的技巧.分享给大家供大家参考.具体方法如下: 通常来说,php支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现. HTTP断点续传原理: Http头 Range.Content-Range() HTTP头中一般断点下载时才用到Range和Content-Range实体头, Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300) Content-Range用

  • php下载远程文件类(支持断点续传)

    简易使用方法:  复制代码 代码如下: $object = new httpdownload(); $object->set_byfile($file)%N#H#%;//服务器文件名,包括路径 $object->filename = $filename;//下载另存为的文件名 $object->download(); 3.源文件: 复制代码 代码如下: <? class httpdownload { var $data = null; var $data_len = 0; var

  • 关于php支持分块与断点续传文件下载功能代码

    本文章要介绍了这篇文章是一篇关于php流下载,就是可以支持分块与断点续传文件下载,有需要的朋友可以看看.代码如下 复制代码 代码如下: $dowmFile = dirname ( __FILE__ ) . '/Nokia – Always Here.mp3′; //要下载的文件,绝对或相对 $dowmName = 'Nokia – Always Here.mp3′; ob_start (); getlocalfile ( $dowmFile, $dowmName ); flush (); ob_

  • 解决PHP超大文件下载,断点续传下载的方法详解

    最近导出的时候出现一个php内存溢出的问题,原因就是在于下载的时候读取生成的临时文件过大,PHP内存无法容纳,一开如是想到更改PHP内存限制,但是这个只是一个缓兵之计,于是想到了另外一个方法是把文件分次读取,并下载. 以下是源代码: 复制代码 代码如下: <?php $sourceFile = "1.tmp"; //要下载的临时文件名 $outFile = "用户订单.xls"; //下载保存到客户端的文件名 $file_extension = strtolo

  • PHP实现文件下载断点续传详解

    如果我们的网站提供文件下载的服务,那么通常我们都希望下载可以断点续传(Resumable Download),也就是说用户可以暂停下载,并在未来的某个时间从暂停处继续下载,而不必重新下载整个文件. 通常情况下,Web服务器(如Apache)会默认开启对断点续传的支持.因此,如果直接通过Web服务器来提供文件的下载,可以不必做特别的配置,即可享受到断点续传的好处.由于这些文件直接通过Web服务器来提供下载,后端脚本无法对这个下载过程进行控制.这对于仅提供公开.静态文件的网站来说不是问题,但对于需要

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

    php实现大文件断点续传下载实例,看完你就知道超过100M以上的大文件如何断点传输了,这个功能还是比较经典实用的,毕竟大文件上传功能经常用得到. require_once('download.class.php'); date_default_timezone_set('Asia/Shanghai'); error_reporting(E_STRICT); function errorHandler($errno, $errstr, $errfile, $errline) { echo '<p>

  • java 文件大数据Excel下载实例代码

    java 文件大数据Excel下载实例代码 excel可以用xml表示.故可以以此来实现边写边下载文件 package com.tydic.qop.controller; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.I

  • 基于html5+java实现大文件上传实例代码

    废话不多说了,直接给大家贴代码了,具体代码如下所示: html代码如下: <body> <input id="fileid" type="file" accept="video/*;capture=camera" onchange="onfile(this)"> <input id="btn" type="button" value="提交&quo

  • PHP下载文件的函数实例代码

    通过函数完成下载文件的PHP功能代码 function download($url, $filename) { // 获得文件大小, 防止超过2G的文件, 用sprintf来读 $filesize = sprintf ( "%u", filesize ( $url ) ); if (! $filesize) { return; } header ( "Content-type:application/octet-stream\n" ); //application/

  • python 多线程将大文件分开下载后在合并的实例

    废话不多说了,上代码吧: import threading import requests import time import os class Mythread(threading.Thread): def __init__(self,url,startpos,endpos,f): super(Mythread,self).__init__() self.url=url self.startpos=startpos self.endpos=endpos self.fd=f def downl

  • springboot 中文件上传下载实例代码

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置.通过这种方式,Spring Boot致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者. Spring Boot特点 1. 创建独立的Spring应用程序 2. 嵌入的Tomcat,无需部署WAR文件 3. 简化Maven配置 4. 自动配置Spr

  • Java超详细大文件分片上传代码

    目录 Java 大文件分片上传 首先是交互的控制器 上传文件分片参数接收 大文件分片上传服务类实现 文件分片上传定义公共服务类接口 文件分片上传文件操作接口实现类 OSS阿里云对象存储分片上传实现 京东云对象存储实现 腾讯云对象存储分片上传 分片上传前端代码实现 Java 大文件分片上传 原理:前端通过js读取文件,并将大文件按照指定大小拆分成多个分片,并且计算每个分片的MD5值.前端将每个分片分别上传到后端,后端在接收到文件之后验证当前分片的MD5值是否与上传的MD5一致,待所有分片上传完成之

  • java实现文件断点续传下载功能

    本文实例为大家分享了java断点续传下载的代码,供大家参考,具体内容如下 1. Java代码     //实现文件下载功能 public String downloadFile(){ File dir = new File(filepath);//获取文件路劲 if(!dir.exists()) { System.out.println("文件路径错误"); log.debug("文件路径错误"); return "failed";// 判断文件

  • JavaScript 中如何实现大文件并行下载

    目录 一.HTTP 范围请求 1.1 Range 语法 二.如何实现大文件下载 2.1 定义辅助函数 2.2 大文件下载使用示例 三.总结 相信有些小伙伴已经了解大文件上传的解决方案,在上传大文件时,为了提高上传的效率,我们一般会使用 Blob.slice 方法对大文件按照指定的大小进行切割,然后在开启多线程进行分块上传,等所有分块都成功上传后,再通知服务端进行分块合并. 那么对大文件下载来说,我们能否采用类似的思想呢?在服务端支持 Range 请求首部的条件下,我们也是可以实现多线程分块下载的

  • Python 工具类实现大文件断点续传功能详解

    依赖 os.sys.requests 工具代码 废话不多说,上代码. #!/usr/bin/env python3 # -*- coding: utf-8 -*- """ Created on Sat Oct 23 13:54:39 2021 @author: huyi """ import os import sys import requests def download(url, file_path): # 重试计数 count = 0 #

随机推荐