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生成带有雪花背景的验证码
Sep 28 PHP
PHP动态创建Web站点的方法
Aug 14 PHP
使用 PHPMAILER 发送邮件实例应用
Nov 07 PHP
php将access数据库转换到mysql数据库的方法
Dec 24 PHP
我整理的PHP 7.0主要新特性
Jan 07 PHP
PHP编写登录验证码功能 附调用方法
May 19 PHP
WordPress过滤垃圾评论的几种主要方法小结
Jul 11 PHP
PHP常用函数总结(180多个)
Dec 25 PHP
php 一维数组的循环遍历实现代码
Apr 10 PHP
基于php编程规范(详解)
Aug 17 PHP
php实现mysql连接池效果实现代码
Jan 25 PHP
PHP5中使用mysqli的prepare操作数据库的介绍
Mar 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
短波的认识
2021/03/01 无线电
php使用fgetcsv读取csv文件出现乱码的解决方法
2014/11/08 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
2019/05/13 PHP
使Ext的Template可以解析二层的json数据的方法
2007/12/22 Javascript
用cssText批量修改样式
2009/08/29 Javascript
实现局部遮罩与关闭原理及代码
2013/02/04 Javascript
浅谈javascript的call()、apply()、bind()的用法
2016/02/21 Javascript
javascript每日必学之封装
2016/02/23 Javascript
JS根据生日月份和日期计算星座的简单实现方法
2016/11/24 Javascript
jQuery EasyUI之验证框validatebox实例详解
2017/04/10 jQuery
详解如何使用webpack+es6开发angular1.x
2017/08/16 Javascript
Mac下通过brew安装指定版本的nodejs教程
2018/05/17 NodeJs
浅谈node中的cluster集群
2018/06/02 Javascript
JavaScript指定断点操作实例教程
2018/09/18 Javascript
JS/HTML5游戏常用算法之碰撞检测 地图格子算法实例详解
2018/12/12 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
puppeteer库入门初探
2019/01/09 Javascript
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
2018/03/19 Python
Python根据已知邻接矩阵绘制无向图操作示例
2018/06/23 Python
python opencv将图片转为灰度图的方法示例
2019/07/31 Python
python sorted方法和列表使用解析
2019/11/18 Python
python异常处理之try finally不报错的原因
2020/05/18 Python
Python使用Matlab命令过程解析
2020/06/04 Python
python缩进长度是否统一
2020/08/02 Python
芝加哥牛排公司:Chicago Steak Company
2018/10/31 全球购物
公司培训欢迎词
2014/01/10 职场文书
《恐龙》教学反思
2014/04/27 职场文书
献爱心活动总结
2014/05/07 职场文书
承诺书样本
2014/08/30 职场文书
2014四风问题对照检查材料范文
2014/09/15 职场文书
群众路线对照检查剖析材料
2014/10/09 职场文书
2015年社区综治宣传月活动总结
2015/03/25 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
2021/06/04 Oracle
90后经典动画片排行:《数码宝贝》第二,《小鲤鱼历险记》在榜
2022/03/18 日漫
Python绘制散乱的点构成的图的方法
2022/04/21 Python