小标
2018-07-12
来源 :
阅读 1344
评论 0
摘要:本文主要向大家介绍了PHP语言 支持断点续传的文件下载类,通过具体的实例向大家展示,希望对大家学习php语言有所帮助。
本文主要向大家介绍了PHP语言 支持断点续传的文件下载类,通过具体的实例向大家展示,希望对大家学习php语言有所帮助。
php 支持断点续传,主要依靠HTTP协议中 header HTTP_RANGE实现。
HTTP断点续传原理
Http头 Range、Content-Range()
HTTP头中一般断点下载时才用到Range和Content-Range实体头,
Range用户请求头中,指定第一个字节的位置和最后一个字节的位置,如(Range:200-300)
Content-Range用于响应头
请求下载整个文件:
GET /test.rar HTTP/1.1
Connection: close
Host: 116.1.219.219
Range: bytes=0-801 //一般请求下载整个文件是bytes=0- 或不用这个头
一般正常回应
HTTP/1.1 200 OK
Content-Length: 801
Content-Type: application/octet-stream
Content-Range: bytes 0-800/801 //801:文件总大小
FileDownload.class.php
[php] view plain copy
1. <?php
2. /** php下载类,支持断点续传
3. * Date: 2013-06-30
4. * Author: fdipzone
5. * Ver: 1.0
6. *
7. * Func:
8. * download: 下载文件
9. * setSpeed: 设置下载速度
10. * getRange: 获取header中Range
11. */
12.
13. class FileDownload{ // class start
14.
15. private $_speed = 512; // 下载速度
16.
17.
18. /** 下载
19. * @param String $file 要下载的文件路径
20. * @param String $name 文件名称,为空则与下载的文件名称一样
21. * @param boolean $reload 是否开启断点续传
22. */
23. public function download($file, $name='', $reload=false){
24. if(file_exists($file)){
25. if($name==''){
26. $name = basename($file);
27. }
28.
29. $fp = fopen($file, 'rb');
30. $file_size = filesize($file);
31. $ranges = $this->getRange($file_size);
32.
33. header('cache-control:public');
34. header('content-type:application/octet-stream');
35. header('content-disposition:attachment; filename='.$name);
36.
37. if($reload && $ranges!=null){ // 使用续传
38. header('HTTP/1.1 206 Partial Content');
39. header('Accept-Ranges:bytes');
40.
41. // 剩余长度
42. header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));
43.
44. // range信息
45. header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));
46.
47. // fp指针跳到断点位置
48. fseek($fp, sprintf('%u', $ranges['start']));
49. }else{
50. header('HTTP/1.1 200 OK');
51. header('content-length:'.$file_size);
52. }
53.
54. while(!feof($fp)){
55. echo fread($fp, round($this->_speed*1024,0));
56. ob_flush();
57. //sleep(1); // 用于测试,减慢下载速度
58. }
59.
60. ($fp!=null) && fclose($fp);
61.
62. }else{
63. return '';
64. }
65. }
66.
67.
68. /** 设置下载速度
69. * @param int $speed
70. */
71. public function setSpeed($speed){
72. if(is_numeric($speed) && $speed>16 && $speed<4096){
73. $this->_speed = $speed;
74. }
75. }
76.
77.
78. /** 获取header range信息
79. * @param int $file_size 文件大小
80. * @return Array
81. */
82. private function getRange($file_size){
83. if(isset($_SERVER['HTTP_RANGE']) && !empty($_SERVER['HTTP_RANGE'])){
84. $range = $_SERVER['HTTP_RANGE'];
85. $range = preg_replace('/[\s|,].*/', '', $range);
86. $range = explode('-', substr($range, 6));
87. if(count($range)<2){
88. $range[1] = $file_size;
89. }
90. $range = array_combine(array('start','end'), $range);
91. if(empty($range['start'])){
92. $range['start'] = 0;
93. }
94. if(empty($range['end'])){
95. $range['end'] = $file_size;
96. }
97. return $range;
98. }
99. return null;
100. }
101.
102. } // class end
103.
104. ?>
demo
[php] view plain copy
1. <?php
2.
3. require('FileDownload.class.php');
4. $file = 'book.zip';
5. $name = time().'.zip';
6. $obj = new FileDownload();
7. $flag = $obj->download($file, $name);
8. //$flag = $obj->download($file, $name, true); // 断点续传
9.
10. if(!$flag){
11. echo 'file not exists';
12. }
13.
14. ?>
断点续传测试方法:
使用linux wget命令去测试下载, wget -c -O file //xxx
1.先关闭断点续传
$flag = $obj->download($file, $name);
[plain] view plain copy
1. fdipzone@ubuntu:~/Downloads$ wget -O test.rar //demo.fdipzone.com/demo.php
2. --2013-06-30 16:52:44-- //demo.fdipzone.com/demo.php
3. 正在解析主机 demo.fdipzone.com... 127.0.0.1
4. 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
5. 已发出 HTTP 请求,正在等待回应... 200 OK
6. 长度: 10445120 (10.0M) [application/octet-stream]
7. 正在保存至: “test.rar”
8.
9. 30% [============================> ] 3,146,580 513K/s 估时 14s
10. ^C
11. fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar //demo.fdipzone.com/demo.php
12. --2013-06-30 16:52:57-- //demo.fdipzone.com/demo.php
13. 正在解析主机 demo.fdipzone.com... 127.0.0.1
14. 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
15. 已发出 HTTP 请求,正在等待回应... 200 OK
16. 长度: 10445120 (10.0M) [application/octet-stream]
17. 正在保存至: “test.rar”
18.
19. 30% [============================> ] 3,146,580 515K/s 估时 14s
20. ^C
21.
22. 可以看到,wget -c不能断点续传
2.开启断点续传
$flag = $obj->download($file, $name, true);
[plain] view plain copy
1. fdipzone@ubuntu:~/Downloads$ wget -O test.rar //demo.fdipzone.com/demo.php
2. --2013-06-30 16:53:19-- //demo.fdipzone.com/demo.php
3. 正在解析主机 demo.fdipzone.com... 127.0.0.1
4. 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
5. 已发出 HTTP 请求,正在等待回应... 200 OK
6. 长度: 10445120 (10.0M) [application/octet-stream]
7. 正在保存至: “test.rar”
8.
9. 20% [==================> ] 2,097,720 516K/s 估时 16s
10. ^C
11. fdipzone@ubuntu:~/Downloads$ wget -c -O test.rar //demo.fdipzone.com/demo.php
12. --2013-06-30 16:53:31-- //demo.fdipzone.com/demo.php
13. 正在解析主机 demo.fdipzone.com... 127.0.0.1
14. 正在连接 demo.fdipzone.com|127.0.0.1|:80... 已连接。
15. 已发出 HTTP 请求,正在等待回应... 206 Partial Content
16. 长度: 10445121 (10.0M),7822971 (7.5M) 字节剩余 [application/octet-stream]
17. 正在保存至: “test.rar”
18.
19. 100%[++++++++++++++++++++++++=========================================================================>] 10,445,121 543K/s 花时 14s
20.
21. 2013-06-30 16:53:45 (543 KB/s) - 已保存 “test.rar” [10445121/10445121])
22.
23. 可以看到会从断点的位置(%20)开始下载。
以上就介绍了PHP的相关知识,希望对PHP有兴趣的朋友有所帮助。了解更多内容,请关注职坐标编程语言PHP频道!
喜欢 | 1
不喜欢 | 0
您输入的评论内容中包含违禁敏感词
我知道了

请输入正确的手机号码
请输入正确的验证码
您今天的短信下发次数太多了,明天再试试吧!
我们会在第一时间安排职业规划师联系您!
您也可以联系我们的职业规划师咨询:
版权所有 职坐标-一站式AI+学习就业服务平台 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
沪公网安备 31011502005948号