-
PHP支持断点续传实例代码
让PHP下载代码支持断点续传,主要靠的 HTTP协议中header Content-Range来实现.
先来说说 HTTP的下载原理
对于HTTP协议,向服务器请求某个文件时,只要发送类似如下的请求即可,代码如下:
GET /Path/FileName HTTP/1.0
Host: www.server.com:80
Accept: **表示接收任何类型的数据。User-Agent表示用户代理,这个字段可有可无,但强烈建议加上,因为它是服务器统计、追踪以及识别客户端的依据。Connection字段中的close表示使用非持久连接。
关于HTTP协议更多的细节可以参考RFC2616(HTTP 1.1),因为我只是想通过HTTP协议实现文件下载,所以也只看了一部分,并没有看全。
如果服务器成功收到该请求,并且没有出现任何错误,则会返回类似下面的数据:
- HTTP/1.0 200 OK
- Content-Length: 13057672
- Content-Type: application/octet-stream
- Last-Modified: Wed, 10 Oct 2005 00:56:34 GMT
- Accept-Ranges: bytes
- ETag: "2f38a6cac7cec51:160c"
- Server: Microsoft-IIS/6.0
- X-Powered-By: ASP.NET
- Date: Wed, 16 Nov 2005 01:57:54 GMT
- Connection: close
先定义一个函数 getRange() 这个函数用来处理 header中 Range 具体数据的处理,代码如下:
- /** $file_size 文件大小 */
- function getRange($file_size){
- $range = isset($_SERVER['HTTP_RANGE'])?$_SERVER['HTTP_RANGE']:null;
- if(!emptyempty($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 (emptyempty($range['start'])) {
- $range['start'] = 0;
- }
- if (!isset ($range['end']) || emptyempty($range['end'])) {
- $range['end'] = $file_size;
- }
- return $range;
- }
- return null;
- }
假设文件的地址为 $file_path,代码如下:
- $speed = 512;//此参数为下载最大速度
- $pos = strrpos($file_path, "/");
- $file_name = substr($file_path, $pos+1);
- $file_size = filesize($file_path);
- $ranges = getRange($file_size);
- $fh = fopen($file_path, "rb");
- header('Cache-control: public');
- header('Content-Type: application/octet-stream');
- header('Content-Disposition: attachment; filename='.$file_name);
- if ($ranges != null) {
- 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'], $file_size));
- fseek($fh, sprintf('%u',$ranges['start']));
- }else{
- header("HTTP/1.1 200 OK");
- header(sprintf('Content-Length: %s', $file_size));
- }
- while(!feof($fh))
- {
- echo fread($fh, round($speed*1024, 0));
- ob_flush();
- sleep(1);
- }
- ($fh != null) && fclose($fh);
基本如此,就可以解决一般性文件的断点续传或者下载.
原文链接:http://www.phpfensi.com/php/20140730/4062.html
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
SQL SERVER中递归
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
这是目前我见过最好的跨域解决方案!
减少回流与重绘
减少回流与重绘
如何使用KrpanoToolJS在浏览器切图
performance.now() 与 Date.now() 对比
一款纯 JS 实现的轻量化图片编辑器
关于开发 VS Code 插件遇到的 workbench.scm.
前端设计模式——观察者模式
前端设计模式——中介者模式
创建型-原型模式