php可以一次下载几个文件(php实现大文件断点续传下载实例代码)
类别:编程学习 浏览量:1211
时间:2021-10-14 00:05:20 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
您可能感兴趣
- phpweb应用技术开发与数据库教程(IIS8 使用FastCGI配置PHP环境图文教程)
- nginx如何配置php项目(Nginx服务器究竟是怎么执行PHP项目)
- php有几种模式(php 策略模式原理与应用深入理解)
- jqueryajax实现部分刷新(php+jQuery ajax实现的实时刷新显示数据功能示例)
- php框架制作方法(PHP从零开始打造自己的MVC框架之路由类实现方法分析)
- php项目开发实例(php项目中类的自动加载实例讲解)
- php面向对象教程理解(PHP面向对象程序设计之构造方法和析构方法详解)
- phplaravel怎么优化(laravel执行php artisan migrate报错的解决方法)
- php代码最可靠的加密方式(php DES加密算法实例分析)
- php教程7.10.6学习(php5.6.x到php7.0.x特性小结)
- thinkphp权限认证怎么用(ThinkPHP框架结合Ajax实现用户名校验功能示例)
- php防sql注入(万能密码的SQL注入漏洞其PHP环境搭建及防御手段)
- phplaravel一般开发什么项目(laravel 去掉index.php伪静态的操作方法)
- php微信公众号管理后台(php实现微信公众号创建自定义菜单功能的实例代码)
- php商城支付接口(php实现银联商务公众号+服务窗支付的示例代码)
- linux如何安装php7.1.5环境(vmware linux系统安装最新的php7图解)
- 小米Watch S1评测 或许能成为小米冲击高端可穿戴设备的里程碑(小米WatchS1评测或许能成为小米冲击高端可穿戴设备的里程碑)
- 手机QQ与小米路由器在一起 明天揭晓,敬请期待(手机QQ与小米路由器在一起)
- 小米音乐与 QQ 音乐合作,便捷迁移会员(小米音乐与QQ音乐合作)
- 小米推出米兔儿童电话手表奥特曼版,799 元,支持微信 QQ(小米推出米兔儿童电话手表奥特曼版)
- 贾怀胤唱《白龙马》 炸场 了 没想到京剧还能这么玩(贾怀胤唱白龙马)
- 白龙马的改编学生版,快来看看(白龙马的改编学生版)
热门推荐
排行榜
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9