您的位置:首页 > 编程学习 > > 正文

php可以一次下载几个文件(php实现大文件断点续传下载实例代码)

更多 时间:2021-10-14 00:05:20 类别:编程学习 浏览量:1211

php可以一次下载几个文件

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

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

php可以一次下载几个文件(php实现大文件断点续传下载实例代码)

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 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

  • ?
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • /**
  •  * 文件传输,支持断点续传。
  •  * 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实现大文件断点续传下载实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

    原文链接:https://www.cnblogs.com/mrlime/archive/2019/10/01/11615025.html

    您可能感兴趣