php可以一次下载几个文件
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实现大文件断点续传下载实例代码,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!
原文链接:https://www.cnblogs.com/mrlime/archive/2019/10/01/11615025.html