Maison > Article > développement back-end > Classe de téléchargement de fichiers PHP prenant en charge le téléchargement de la reprise du point d'arrêt
php prend en charge la reprise du point d'arrêt, en s'appuyant principalement sur l'en-tête HTTP_RANGE dans le protocole HTTP.
Principe de téléchargement de reprise de point d'arrêt HTTP
Plage d'en-tête HTTP, Content-Range()
Utilisé uniquement pour les téléchargements de points d'arrêt généraux dans la plage d'en-tête HTTP et En-têtes d'entité Content-Range,
En-tête de demande utilisateur Range, spécifiez la position du premier octet et la position du dernier octet, par exemple (Range : 200-300)
Content-Range est utilisé pour l'en-tête de réponse
demandes de téléchargement de l'intégralité du fichier :
GET /test.rar HTTP/1.1
Connexion : fermer
Hôte : 116.1.219.219
Plage : octets=0-801 //Général La demande de téléchargement du fichier entier est bytes=0- ou ne pas utiliser cet en-tête
Réponse généralement normale
HTTP/1.1 200 OK
Content-Length : 801
Content-Type : application /octet-stream
Content-Range : octets 0-800/801 //801 : taille totale du fichier
FileDownload.class.php
<?php /** php下载类,支持断点续传 * Date: 2013-06-30 * Author: fdipzone * Ver: 1.0 * * Func: * download: 下载文件 * setSpeed: 设置下载速度 * getRange: 获取header中Range */ class FileDownload{ // class start private $_speed = 512; // 下载速度 /** 下载 * @param String $file 要下载的文件路径 * @param String $name 文件名称,为空则与下载的文件名称一样 * @param boolean $reload 是否开启断点续传 */ public function download($file, $name='', $reload=false){ if(file_exists($file)){ if($name==''){ $name = basename($file); } $fp = fopen($file, 'rb'); $file_size = filesize($file); $ranges = $this->getRange($file_size); header('cache-control:public'); header('content-type:application/octet-stream'); header('content-disposition:attachment; filename='.$name); if($reload && $ranges!=null){ // 使用续传 header('HTTP/1.1 206 Partial Content'); header('Accept-Ranges:bytes'); // 剩余长度 header(sprintf('content-length:%u',$ranges['end']-$ranges['start'])); // range信息 header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size)); // fp指针跳到断点位置 fseek($fp, sprintf('%u', $ranges['start'])); }else{ header('HTTP/1.1 200 OK'); header('content-length:'.$file_size); } while(!feof($fp)){ echo fread($fp, round($this->_speed*1024,0)); ob_flush(); //sleep(1); // 用于测试,减慢下载速度 } ($fp!=null) && fclose($fp); }else{ return ''; } } /** 设置下载速度 * @param int $speed */ public function setSpeed($speed){ if(is_numeric($speed) && $speed>16 && $speed<4096){ $this->_speed = $speed; } } /** 获取header range信息 * @param int $file_size 文件大小 * @return Array */ private function getRange($file_size){ if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){ $range = $_SERVER['HTTP_RANGE']; $range = preg_replace('/[\s|,].*/', '', $range); $range = explode('-', substr($range, 6)); if(count($range)<2){ $range[1] = $file_size; } $range = array_combine(array('start','end'), $range); if(empty($range['start'])){ $range['start'] = 0; } if(empty($range['end'])){ $range['end'] = $file_size; } return $range; } return null; } } // class end ?>
démo
<?php require('FileDownload.class.php'); $file = 'book.zip'; $name = time().'.zip'; $obj = new FileDownload(); $flag = $obj->download($file, $name); //$flag = $obj->download($file, $name, true); // 断点续传 if(!$flag){ echo 'file not exists'; } ?>
Méthode de test de reprise du point d'arrêt :
Utilisez la commande Linux wget pour tester le téléchargement, wget -c -O fichier http://www.php.cn/
1. Désactivez d'abord la reprise du point d'arrêt
$flag = $obj->download($file, $name);
fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://www.php.cn/ --2013-06-30 16:52:44-- http://www.php.cn/ 正在解析主机 demo.fdipzone.com... 127.0.0.1 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度: 10445120 (10.0M) [application/octet-stream] 正在保存至: “test.rar” 30% [============================> ] 3,146,580 513K/s 估时 14s ^C fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://www.php.cn/ --2013-06-30 16:52:57-- http://www.php.cn/ 正在解析主机 demo.fdipzone.com... 127.0.0.1 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度: 10445120 (10.0M) [application/octet-stream] 正在保存至: “test.rar” 30% [============================> ] 3,146,580 515K/s 估时 14s ^C 可以看到,wget -c不能断点续传
2. Activer la reprise du point d'arrêt
$flag = $obj->download($file, $name, true);
fdipzone@ubuntu:~/Downloads$ wget -O test.rar http://www.php.cn/ --2013-06-30 16:53:19-- http://www.php.cn/ 正在解析主机 demo.fdipzone.com... 127.0.0.1 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 200 OK 长度: 10445120 (10.0M) [application/octet-stream] 正在保存至: “test.rar” 20% [==================> ] 2,097,720 516K/s 估时 16s ^C fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar http://www.php.cn/ --2013-06-30 16:53:31-- http://www.php.cn/ 正在解析主机 demo.fdipzone.com... 127.0.0.1 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。 已发出 HTTP 请求,正在等待回应... 206 Partial Content 长度: 10445121 (10.0M),7822971 (7.5M) 字节剩余 [application/octet-stream] 正在保存至: “test.rar” 100%[++++++++++++++++++++++++=========================================================================>] 10,445,121 543K/s 花时 14s 2013-06-30 16:53:45 (543 KB/s) - 已保存 “test.rar” [10445121/10445121]) 可以看到会从断点的位置(%20)开始下载。
Ce qui précède est le contenu du téléchargement de fichiers PHP qui prend en charge la reprise du point d'arrêt. Pour plus de contenu connexe, veuillez prêter attention à. Site Web chinois PHP (www.php.cn) !