php下载远程文件类(支持断点续传)


Posted in PHP onNovember 14, 2008

简易使用方法: 

$object = new httpdownload(); 
$object->set_byfile($file)%N#H#%;//服务器文件名,包括路径 
$object->filename = $filename;//下载另存为的文件名 
$object->download();

3.源文件:

<? 
class httpdownload { 
var $data = null; 
var $data_len = 0; 
var $data_mod = 0; 
var $data_type = 0; 
var $data_section = 0; //section download 
var $sentSize=0; 
var $handler = array('auth' => null); 
var $use_resume = true; 
var $use_autoexit = false; 
var $use_auth = false; 
var $filename = null; 
var $mime = null; 
var $bufsize = 2048; 
var $seek_start = 0; 
var $seek_end = -1; 
var $totalsizeref = 0; 
var $bandwidth = 0; 
var $speed = 0; 
function initialize() { 
global $HTTP_SERVER_VARS; 
if ($this->use_auth) //use authentication 
{ 
if (!$this->_auth()) //no authentication 
{ 
header('WWW-Authenticate: Basic realm="Please enter your username and password"'); 
header('HTTP/1.0 401 Unauthorized'); 
header('status: 401 Unauthorized'); 
if ($this->use_autoexit) exit(); 
return false; 
} 
} 
if ($this->mime == null) $this->mime = "application/octet-stream"; //default mime 
if (isset($_SERVER['HTTP_RANGE']) || isset($HTTP_SERVER_VARS['HTTP_RANGE'])) 
{ 
if (isset($HTTP_SERVER_VARS['HTTP_RANGE'])) $seek_range = substr($HTTP_SERVER_VARS['HTTP_RANGE'] , strlen('bytes=')); 
else $seek_range = substr($_SERVER['HTTP_RANGE'] , strlen('bytes=')); 
$range = explode('-',$seek_range); 
if ($range[0] > 0) 
{ 
$this->seek_start = intval($range[0]); 
} 
if ($range[1] > 0) $this->seek_end = intval($range[1]); 
else $this->seek_end = -1; 
if (!$this->use_resume) 
{ 
$this->seek_start = 0; 
//header("HTTP/1.0 404 Bad Request"); 
//header("Status: 400 Bad Request"); 
//exit; 
//return false; 
} 
else 
{ 
$this->data_section = 1; 
} 
} 
else 
{ 
$this->seek_start = 0; 
$this->seek_end = -1; 
} 
$this->sentSize=0; 
return true; 
} 
function header($size,$seek_start=null,$seek_end=null) { 
header('Content-type: ' . $this->mime); 
header('Content-Disposition: attachment; filename="' . $this->filename . '"'); 
header('Last-Modified: ' . date('D, d M Y H:i:s \G\M\T' , $this->data_mod)); 
if ($this->data_section && $this->use_resume) 
{ 
header("HTTP/1.0 206 Partial Content"); 
header("Status: 206 Partial Content"); 
header('Accept-Ranges: bytes'); 
header("Content-Range: bytes $seek_start-$seek_end/$size"); 
header("Content-Length: " . ($seek_end - $seek_start + 1)); 
} 
else 
{ 
header("Content-Length: $size"); 
} 
} 
function download_ex($size) 
{ 
if (!$this->initialize()) return false; 
ignore_user_abort(true); 
//Use seek end here 
if ($this->seek_start > ($size - 1)) $this->seek_start = 0; 
if ($this->seek_end <= 0) $this->seek_end = $size - 1; 
$this->header($size,$seek,$this->seek_end); 
$this->data_mod = time(); 
return true; 
} 
function download() { 
if (!$this->initialize()) return false; 
try 
{ 
error_log("begin download\n", 3,"/usr/local/www/apache22/LOGS/apache22_php.err"); 
$seek = $this->seek_start; 
$speed = $this->speed; 
$bufsize = $this->bufsize; 
$packet = 1; 
//do some clean up 
@ob_end_clean(); 
$old_status = ignore_user_abort(true); 
@set_time_limit(0); 
$this->bandwidth = 0; 
$size = $this->data_len; 
if ($this->data_type == 0) //download from a file 
{ 
$size = filesize($this->data); 
if ($seek > ($size - 1)) $seek = 0; 
if ($this->filename == null) $this->filename = basename($this->data); 
$res = fopen($this->data,'rb'); 
if ($seek) fseek($res , $seek); 
if ($this->seek_end < $seek) $this->seek_end = $size - 1; 
$this->header($size,$seek,$this->seek_end); //always use the last seek 
$size = $this->seek_end - $seek + 1; 
while (!(connection_aborted() || connection_status() == 1) && $size > 0) 
{ 
if ($size < $bufsize) 
{ 
echo fread($res , $size); 
$this->bandwidth += $size; 
$this->sentSize+=$size; 
} 
else 
{ 
echo fread($res , $bufsize); 
$this->bandwidth += $bufsize; 
$this->sentSize+=$bufsize; 
} 
$size -= $bufsize; 
flush(); 
if ($speed > 0 && ($this->bandwidth > $speed*$packet*1024)) 
{ 
sleep(1); 
$packet++; 
} 
} 
fclose($res); 
} 
elseif ($this->data_type == 1) //download from a string 
{ 
if ($seek > ($size - 1)) $seek = 0; 
if ($this->seek_end < $seek) $this->seek_end = $this->data_len - 1; 
$this->data = substr($this->data , $seek , $this->seek_end - $seek + 1); 
if ($this->filename == null) $this->filename = time(); 
$size = strlen($this->data); 
$this->header($this->data_len,$seek,$this->seek_end); 
while (!connection_aborted() && $size > 0) { 
if ($size < $bufsize) 
{ 
$this->bandwidth += $size; 
$this->sentSize+=$size; 
} 
else 
{ 
$this->bandwidth += $bufsize; 
$this->sentSize+=$bufsize; 
} 
echo substr($this->data , 0 , $bufsize); 
$this->data = substr($this->data , $bufsize); 
$size -= $bufsize; 
flush(); 
if ($speed > 0 && ($this->bandwidth > $speed*$packet*1024)) 
{ 
sleep(1); 
$packet++; 
} 
} 
} else if ($this->data_type == 2) { 
//just send a redirect header 
header('location: ' . $this->data); 
} 
if($this->totalsizeref==$this->sentSize )error_log("end download\n", 3,"/usr/local/www/apache22/LOGS/apache22_php.err"); 
else error_log("download is canceled\n", 3,"/usr/local/www/apache22/LOGS/apache22_php.err"); 
if ($this->use_autoexit) exit(); 
//restore old status 
ignore_user_abort($old_status); 
set_time_limit(ini_get("max_execution_time")); 
} 
catch(Exception $e) 
{ 
error_log("cancel download\n".$e, 3,"/usr/local/www/apache22/LOGS/apache22_php.err"); 
} 
return true; 
} 
function set_byfile($dir) { 
if (is_readable($dir) && is_file($dir)) { 
$this->data_len = 0; 
$this->data = $dir; 
$this->data_type = 0; 
$this->data_mod = filemtime($dir); 
$this->totalsizeref = filesize($dir); 
return true; 
} else return false; 
} 
function set_bydata($data) { 
if ($data == '') return false; 
$this->data = $data; 
$this->data_len = strlen($data); 
$this->data_type = 1; 
$this->data_mod = time(); 
return true; 
} 
function set_byurl($data) { 
$this->data = $data; 
$this->data_len = 0; 
$this->data_type = 2; 
return true; 
} 
function set_lastmodtime($time) { 
$time = intval($time); 
if ($time <= 0) $time = time(); 
$this->data_mod = $time; 
} 
function _auth() { 
if (!isset($_SERVER['PHP_AUTH_USER'])) return false; 
if (isset($this->handler['auth']) && function_exists($this->handler['auth'])) 
{ 
return $this->handler['auth']('auth' , $_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']); 
} 
else return true; //you must use a handler 
} 
} 
?>

PHP 相关文章推荐
用来给图片加水印的PHP类
Apr 09 PHP
php cli 方式 在crotab中运行解决
Feb 08 PHP
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
Dec 05 PHP
跨浏览器PHP下载文件名中的中文乱码问题解决方法
Mar 05 PHP
PHP也能干大事之PHP中的编码解码详解
Apr 20 PHP
PHP中empty和isset对于参数结构的判断及empty()和isset()的区别
Nov 15 PHP
PHP实现仿百度文库,豆丁在线文档效果(word,excel,ppt转flash)
Mar 10 PHP
PHPWind9.0手动屏蔽验证码解决后台关闭验证码但是依然显示的问题
Aug 12 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
Sep 22 PHP
PHP使用phpunit进行单元测试示例
Sep 23 PHP
php实现推荐功能的简单实例
Sep 29 PHP
PHP cookie与session会话基本用法实例分析
Nov 18 PHP
PHP ajax 分页类代码
Nov 13 #PHP
使用Limit参数优化MySQL查询的方法
Nov 12 #PHP
mysql limit查询优化分析
Nov 12 #PHP
令PHP初学者头疼十四条问题大总结
Nov 12 #PHP
PHP程序61条面向对象分析设计的经验小结
Nov 12 #PHP
Php Cookie的一个使用注意点
Nov 08 #PHP
MySql 按时间段查询数据方法(实例说明)
Nov 02 #PHP
You might like
PHP中的函数-- foreach()的用法详解
2013/06/24 PHP
PHP封装mysqli基于面向对象的mysql数据库操作类与用法示例
2019/02/25 PHP
js借助ActiveXObject实现创建文件
2013/09/29 Javascript
JS控制日期显示的小例子
2013/11/23 Javascript
js中setTimeout()与clearTimeout()用法实例浅析
2015/05/12 Javascript
jQuery实现TAB选项卡切换特效简单演示
2016/03/04 Javascript
Ubuntu系统下Angularjs开发环境安装
2016/09/01 Javascript
js 获取本地文件及目录的方法(推荐)
2016/11/10 Javascript
JavaScript面向对象分层思维全面解析
2016/11/22 Javascript
js随机生成一个验证码
2017/06/01 Javascript
在iframe中使bootstrap的模态框在父页面弹出问题
2017/08/07 Javascript
js使用swiper实现层叠轮播效果实例代码
2018/12/12 Javascript
微信小程序利用button控制条件标签的变量问题
2020/03/15 Javascript
基于JS实现操作成功之后自动跳转页面
2020/09/25 Javascript
echarts浮动显示单位的实现方法示例
2020/12/04 Javascript
jQuery实现穿梭框效果
2021/01/19 jQuery
python使用在线API查询IP对应的地理位置信息实例
2014/06/01 Python
举例讲解Python程序与系统shell交互的方式
2015/04/09 Python
基于wxpython实现的windows GUI程序实例
2015/05/30 Python
Python脚本实现Web漏洞扫描工具
2016/10/25 Python
Python3使用正则表达式爬取内涵段子示例
2018/04/22 Python
对python多线程中Lock()与RLock()锁详解
2019/01/11 Python
Django接收post前端返回的json格式数据代码实现
2019/07/31 Python
django处理select下拉表单实例(从model到前端到post到form)
2020/03/13 Python
利用python对mysql表做全局模糊搜索并分页实例
2020/07/12 Python
解决python运行效率不高的问题
2020/07/20 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
GNC健安喜美国官网:美国第一营养品牌
2016/07/22 全球购物
The Beach People美国:澳洲海滨奢华品牌
2018/07/05 全球购物
几个SQL的面试题
2014/03/08 面试题
extern是什么意思
2016/03/10 面试题
应用电子技术专业个人求职信
2013/09/21 职场文书
社区巾帼文明岗事迹材料
2014/06/03 职场文书
关于读书的演讲稿300字
2014/08/27 职场文书
公司员工体检通知
2015/04/21 职场文书
python的列表生成式,生成器和generator对象你了解吗
2022/03/16 Python