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

吾爱主题 阅读:198 2021-08-25 15:41:00 评论:0

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

 

?
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

可以去百度分享获取分享代码输入这里。
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

【腾讯云】云服务器产品特惠热卖中
搜索
标签列表
    关注我们

    了解等多精彩内容