PHP大檔案下載(方式2支援斷點續傳)

技術小美發表於2017-11-14

/** php下載類,支援斷點續傳 可能是伺服器原因 配置較低 下載一段伺服器會崩潰 下載也會停止


  • 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 ();

    }













本文轉自lb沫51CTO部落格,原文連結:http://blog.51cto.com/13562606/2066551,如需轉載請自行聯絡原作者


相關文章