File Download Class Supporting Breakpoint Continued Transfer Implemented by php
- 2021-07-21 07:54:33
- OfStack
This article describes the example of php to support the breakpoint continued transmission of the file download class and its usage, is a very practical skills. Share it for your reference. The specific methods are as follows:
Generally speaking, php supports breakpoint continuous transmission, which is mainly implemented by header HTTP_RANGE in HTTP protocol.
Principle of HTTP breakpoint continuous transmission:
Http header Range, Content-Range ()
Range and Content-Range entity headers are only used when downloading one breakpoint in HTTP header,
In the Range user request header, specify the position of the first byte and the position of the last byte, such as (Range: 200-300)
Content-Range for response headers
Request to download the entire file:
GET /test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219
Range: bytes=0-801//1 Request to download the entire file is bytes=0-or without this header
1 normal response:
HTTP/1.1 200 OK
Content-Length: 801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801//801: Total file size
The code for the FileDownload. class. php class file is as follows:
<?php
/** php Download class , Support breakpoint continuous transmission
* Date: 2013-06-30
* Author: test
* Ver: 1.0
*
* Func:
* download: Download a file
* setSpeed: Set the download speed
* getRange: Get header Medium Range
*/
class FileDownload{ // class start
private $_speed = 512; // Download speed
/** Download
* @param String $file The file path to download
* @param String $name File name , If it is empty, it is the same as the downloaded file name 1 Sample
* @param boolean $reload Whether to turn on breakpoint resume transmission
*/
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){ // Use continued transmission
header('HTTP/1.1 206 Partial Content');
header('Accept-Ranges:bytes');
// Remaining length
header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
// range Information
header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
// fp The pointer skips to the breakpoint position
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); // Used for testing , Slow down the download speed
}
($fp!=null) && fclose($fp);
}else{
return '';
}
}
/** Set the download speed
* @param int $speed
*/
public function setSpeed($speed){
if(is_numeric($speed) && $speed>16 && $speed<4096){
$this->_speed = $speed;
}
}
/** Get header range Information
* @param int $file_size 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
?>
The sample code for demo is as follows:
<?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); // Breakpoint transmission
if(!$flag){
echo 'file not exists';
}
?>
Breakpoint continuous transmission test method:
Use the linux wget command to test the download, wget-c-O file http://xxx
1. Close the breakpoint and continue transmission first
$flag = $obj->download($file, $name);
test@ubuntu:~/Downloads$ wget -O test.rar http://demo.test.com/demo.php
--2013-06-30 16:52:44-- http://demo.test.com/demo.php
Resolving host demo.test.com... 127.0.0.1
Connecting demo.test.com|127.0.0.1|:80... Already connected.
Issued HTTP Request, waiting for response ... 200 OK
Length: 10445120 (10.0M) [application/octet-stream]
Saving to : " test.rar "
30% [============================> ] 3,146,580 513K/s Estimated time 14s
^C
test@ubuntu:~/Downloads$ wget -c -O test.rar http://demo.test.com/demo.php
--2013-06-30 16:52:57-- http://demo.test.com/demo.php
Resolving host demo.test.com... 127.0.0.1
Connecting demo.test.com|127.0.0.1|:80... Already connected.
Issued HTTP Request, waiting for response ... 200 OK
Length: 10445120 (10.0M) [application/octet-stream]
Saving to : " test.rar "
30% [============================> ] 3,146,580 515K/s Estimated time 14s
^C
It can be seen that wget-c cannot be continued at breakpoint
2. Open the breakpoint to continue transmission
$flag = $obj->download($file, $name, true);
test@ubuntu:~/Downloads$ wget -O test.rar http://demo.test.com/demo.php
--2013-06-30 16:53:19-- http://demo.test.com/demo.php
Resolving host demo.test.com... 127.0.0.1
Connecting demo.test.com|127.0.0.1|:80... Already connected.
Issued HTTP Request, waiting for response ... 200 OK
Length: 10445120 (10.0M) [application/octet-stream]
Saving to : " test.rar "
20% [==================> ] 2,097,720 516K/s Estimated time 16s
^C
test@ubuntu:~/Downloads$ wget -c -O test.rar http://demo.test.com/demo.php
--2013-06-30 16:53:31-- http://demo.test.com/demo.php
Resolving host demo.test.com... 127.0.0.1
Connecting demo.test.com|127.0.0.1|:80... Already connected.
Issued HTTP Request, waiting for response ... 206 Partial Content
Length: 10445121 (10.0M) , 7822971 (7.5M) Byte residue [application/octet-stream]
Saving to : " test.rar "
100%[++++++++++++++++++++++++=========================================================================>] 10,445,121 543K/s Flower time 14s
2013-06-30 16:53:45 (543 KB/s) - Saved " test.rar " [10445121/10445121])
You can see that the download will begin at the location of the breakpoint (% 20).
The complete source code of this example can be downloaded here.
I believe that this paper has a certain reference value for everyone's PHP programming.