Home > Article > Backend Development > How to implement file download breakpoint resume in PHP
This article mainly shares with you how to implement file download breakpoint resuming in PHP. I hope it can help you. If our website provides file download services, then we usually hope that the download can be resumable (Resumable Download), which means that the user can pause the download and continue downloading from the pause point at some time in the future without having to restart. Download the entire file.
Normally, web servers (such as Apache) will enable support for resumed downloads by default. Therefore, if you provide file downloads directly through the Web server, you can enjoy the benefits of resumed downloading without making special configurations. Since these files are provided for download directly through the web server, the back-end script cannot control the download process. This is not a problem for websites that only provide public, static files, but for websites that need to provide private, dynamic files, providing downloads directly through the Web server cannot meet the needs. At this time, you need to add support for breakpoint resume downloading when writing the background script program.
This article will use PHP as an example to briefly introduce the method of resuming file downloads.
Principle
The principle of breakpoint resume transmission is relatively intuitive.
The HTTP protocol specifies how to transmit part of a resource, not all of it. For example, if the size of a file is 1000 bytes, the browser can only request the first 300 bytes of the file, or only the 500th to 1000th bytes. This way, instead of transmitting the entire content of a resource in one request, you can make multiple requests, each requesting only a portion of the content. After all these requests are returned, the obtained content is spliced piece by piece to obtain the complete resource.
To implement breakpoint resumption is to make use of the above characteristics of the http protocol. When the user pauses the download, the browser will record the downloaded location. When the user resumes the download at some time in the future, the download can be continued from the last paused location without having to start from the beginning.
Implementation
Since partial transmission is not mandatory and the server may or may not support it, we need to tell the browser in the program whether the resource it requests supports partial transmission. This can be accomplished by setting the HTTP Accept-Ranges response header. The PHP code is as follows:
The code is as follows:
header('Accept-Ranges: bytes');
Accept-Ranges: bytes tells the browser that the resource supports partial transmission in bytes. This response header needs to be appended to all resources that support partial transfers.
When receiving a request, we need to extract from the browser's request which part of the resource the browser is requesting. This information is passed through the Range request header. In PHP, it is stored in $_SERVER['HTTP_RANGE']. We need to check whether this variable is defined, if so, use the value, otherwise, set the range to the entire resource.
The code is as follows:
$range = "0-". ($content_length-1); if(isset($_SERVER['HTTP_RANGE'])){ $range = $_SERVER['HTTP_RANGE']; }
Next, you need to analyze the value of $range to decide which part of the resource to return. Possible value examples:
The code is as follows:
100-200 // 第100到第200字节 500- // 第500字节到文件末尾 -1000 // 最后的1000个字节
It should be noted here that after getting a Range, you need to check its value, including:
1 .The starting position is non-negative
2. The ending position needs to be greater than the starting position
3. The starting position needs to be less than the file length minus one (because the position index here starts from 0)
4. If the end position is greater than the file length minus one, you need to set its value to the file length minus one
如果Range的取值不合法,则需要终止程序并告知浏览器:
代码如下:
header('HTTP/1.1 416 Requested Range Not Satisfiable');
为了保持文章简洁,具体的校验代码这里就不提供了。下面假定你已经校验了Range的取值,并得到了 $start 和 $end 两个变量,分别表示开始位置和结束位置。
接下来要做的就是把文件的对应部分的内容发送给浏览器。不过要注意的是,这里涉及到需要发送多个HTTP响应头信息,具体如下:
代码如下:
header('HTTP/1.1 206 Partial Content'); header('Accept-Ranges: bytes'); header("Content-Range: bytes $start-$end/$filesize"); $length = $end - $start + 1; header("Content-Length: $length"); /* 输出文件的指定部分 */
这里的$length需要注意一下,它的取值是本次传输的内容的长度,而不是整个文件的长度。另外需要注意的一点是,这里的HTTP状态码是206,不是200。
总结
文件下载的断点续传实际上是利用了HTTP协议中对传输部分文件的支持。而HTTP协议的这一特性不仅可以用于实现断点续传,客户端程序也可以利用它来实现多线程下载。
在实现断点续传的过程中,需要注意正确设置各种HTTP头信息。错误的头信息将导致用户下载到的文件损坏,无法使用。
相关推荐:
The above is the detailed content of How to implement file download breakpoint resume in PHP. For more information, please follow other related articles on the PHP Chinese website!