PHP 大文件下载(方式2 支持断点续传)

轻巧易行使用方法: 
复制代码 代码如下:
$object = new httpdownload();
$object->set_byfile($file)%N#H#%;//服务器文件名,饱含路线
$object->filename = $filename;//下载另存为的文本名
$object->download();

 

/** php下载类,援救断点续传 恐怕是服务器原因 配置非常的低下载生龙活虎段服务器会崩溃 下载也会告风流洒脱段落

3.源文件:
复制代码 代码如下:

1.效率:匡助断点续传的下载,能总括传输率,能操纵传输率


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
}
}
?>

简短使用方法:

  • Func:
  • download: 下载文件
  • setSpeed: 设置下载速度
  • getRange: 获取header中Range
    */

    private $_speed = 0.1; // 下载速度

    /** 下载

    • @param String $file 要下载的文本路径
    • @param String $name 文件名称,为空则与下载的文件名称同样
    • @param boolean $reload 是还是不是开启断点续传
      */
      public function downloadob($file, $name=”, $reload=false){
      if(file_exists($file)){
      if($name==”){
      $name = basename($file);
      }

      $fp = fopen($file, 'rb');  
      $file_size = filesize($file);  
      $ranges = $this->getRange($file_size);  
      
      header('cache-control:public');  
      header('content-type:application/octet-stream');  
      header('content-disposition:attachment; filename='.$name);  
      
      if($reload && $ranges!=null){ // 使用续传  
          header('HTTP/1.1 206 Partial Content');  
          header('Accept-Ranges:bytes');  
      
          // 剩余长度  
          header(sprintf('content-length:%u',$ranges['end']-$ranges['start']));  
      
          // range信息  
          header(sprintf('content-range:bytes %s-%s/%s', $ranges['start'], $ranges['end'], $file_size));  
      
          // fp指针跳到断点位置  
          fseek($fp, sprintf('%u', $ranges['start']));  
      }else{  
          header('HTTP/1.1 200 OK');  
          header('content-length:'.$file_size);  
      }  
      
      while(!feof($fp)){  
          echo fread($fp, round($this->_speed*1024,0));  
          ob_flush();  
          //sleep(1); // 用于测试,减慢下载速度  
      }  
      
      ($fp!=null) && fclose($fp);  
      

      }else{
      return ”;
      }
      }

    /** 设置下载速度

    • @param int $speed
      */
      public function setSpeed($speed){
      if(is_numeric($speed) && $speed>16 && $speed<4096){
      $this->_speed = $speed;
      }
      }

    /** 获取header range信息

    • @param int $file_size 文件大小
    • @return Array
      /
      private function getRange($file_size){
      if(isset($_SERVER[‘HTTP_RANGE’]) &&
      !empty($_SERVER[‘HTTP_RANGE’])){
      $range = $_SERVER[‘HTTP_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(empty($range[‘start’])){
      $range[‘start’] = 0;
      }
      if(empty($range[‘end’])){
      $range[‘end’] = $file_size;
      }
      return $range;
      }
      return null;
      }

    public function download(){

    $id = input('id');
    $item = Db::name('imgsubmit')->where(['id'=>$id])->find();
    Db::name('imgsubmit')->where(['id'=>$id])->update(['status'=>1]);
    $tt = ltrim($item['zip'],'uploads/');
    $path = config('upload_path').DS.$tt;
    $arr = explode('/',$path);
    $iname=$item['username'].'_'.$item['order_no'];
    //
    /*$filename = $arr[count($arr)-1];*/
    $filename=$iname.'.zip';
    //$file  =  fopen($path, "rb");
    //$flag = $this->downFile($path); 
    $flag =  $this->downloadob($path, $filename, true); // 断点续传  
        exit ();
    

    }

header(“Content-Type:text/html; charset=utf-8”); include_once
“class.httpdownload.php”; $file = “./upload/File/demo.rar”;
//服务器文件名,满含路线 $filename = “demo(0001卡塔尔国.rar”;
//下载另存为的公文名 if (!$file || !file_exists($file卡塔尔(قطر‎卡塔尔(قطر‎ {
echo(“您要下载的公文不设有,单击<a mce_
>这里</a>重返首页。”State of Qatar; exit(卡塔尔(قطر‎; } $object = new httpdownload(State of Qatar;
$object->set_byfile($file); $object->filename = $filename;
$object->download();

相关文章