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 相关文章推荐
火车头采集器3.0采集图文教程
Mar 17 PHP
Windows IIS PHP 5.2 安装与配置方法
Jun 08 PHP
PHP中读写文件实现代码
Oct 20 PHP
浅析ThinkPHP的模板输出功能
Jul 01 PHP
PHP正则表达式之捕获组与非捕获组
Nov 06 PHP
WordPress分页伪静态加html后缀
Jun 08 PHP
基于win2003虚拟机中apache服务器的访问
Aug 01 PHP
php利用云片网实现短信验证码功能的示例代码
Nov 18 PHP
php格式文件打开的四种方法
Feb 24 PHP
thinkphp5使用无限极分类
Feb 18 PHP
解决laravel5.4下的group by报错的问题
Oct 16 PHP
Yii框架模拟组件调用注入示例
Nov 11 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
ADODB的数据库封包程序库
2006/12/31 PHP
通过PHP修改Linux或Unix口令的方法分享
2012/01/30 PHP
带密匙的php加密解密示例分享
2014/01/29 PHP
php的ZipArchive类用法实例
2014/10/20 PHP
php判断邮箱地址是否存在的方法
2016/02/13 PHP
网页常用特效代码整理
2006/06/23 Javascript
jquery form表单获取内容以及绑定数据
2016/02/24 Javascript
基于HTML模板和JSON数据的JavaScript交互(移动端)
2016/04/06 Javascript
浅谈JavaScript的push(),pop(),concat()方法
2016/06/03 Javascript
Vue2.0利用 v-model 实现组件props双向绑定的优美解决方案
2017/03/13 Javascript
vue中七牛插件使用的实例代码
2017/07/28 Javascript
angular2 ng2 @input和@output理解及示例
2017/10/10 Javascript
深入剖析Express cookie-parser中间件实现示例
2018/02/01 Javascript
js闭包学习心得总结
2018/04/17 Javascript
微信小程序中使用ECharts 异步加载数据实现图表功能
2018/07/13 Javascript
JavaScript根据json生成html表格的示例代码
2018/10/24 Javascript
element-ui 实现响应式导航栏的示例代码
2020/05/08 Javascript
vue实现匀速轮播效果
2020/06/29 Javascript
[03:44]2015国际邀请赛选手档案—Cloud9.NoTail
2015/07/28 DOTA
Python 内置函数complex详解
2016/10/23 Python
python 产生token及token验证的方法
2018/12/26 Python
python中自带的三个装饰器的实现
2019/11/08 Python
使用tensorflow实现矩阵分解方式
2020/02/07 Python
Pytorch十九种损失函数的使用详解
2020/04/29 Python
Python更换pip源方法过程解析
2020/05/19 Python
python tqdm实现进度条的示例代码
2020/11/10 Python
CSS3 倾斜的网页图片库实例教程
2009/11/14 HTML / CSS
8款使用 CSS3 实现超炫的 Loading(加载)的动画效果
2015/03/17 HTML / CSS
Mio Skincare法国官网:身体紧致及孕期身体护理
2018/04/04 全球购物
工作中个人的自我评价
2013/12/31 职场文书
电子专业毕业生自我鉴定
2014/01/22 职场文书
药店主任岗位责任制
2014/02/10 职场文书
2015年党员自我剖析材料
2014/12/17 职场文书
2019最新版劳务派遣管理制度
2019/08/16 职场文书
python xlwt模块的使用解析
2021/04/13 Python
使用react-virtualized实现图片动态高度长列表的问题
2021/05/28 Javascript