php 大文件下載,文件流下載,支持斷點續傳

$fileNewname = 'down.zip';//下載後的文件名
$filename = '20200114.zip';//爲要下載的文件名
$path = __DIR__. "/" . $filename;
if (!file_exists($path)) {//檢測文件是否存在
   echo  "文件不存在!";
   exit;
}
$fileSize =  filesize($path);//文件大小b
header("Cache-Control: public");
header("Content-Type: application/octet-stream");//返回的文件(流形式)
header("Accept-Ranges: bytes");//按照字節大小返回
header("Content-Disposition: attachment; filename=".$fileNewname);
$fp = fopen($path, 'rb');//打開文件
// 使用續傳
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] = $fileSize;
   }
   $range = array_combine(array('start', 'end'), $range);
   if (empty($range['start'])) {
      $range['start'] = 0;
   }
   if (empty($range['end'])) {
       $range['end'] = $fileSize;
   }
   header('HTTP/1.1 206 Partial Content');
   // 剩餘長度
   header(sprintf('content-length:%u',$range['end']-$range['start']));
   // range信息
   header(sprintf('content-range:bytes %s-%s/%s', $range['start'], $range['end'], $fileSize));
   // fp指針跳到斷點位置
   fseek($fp, sprintf('%u', $range['start']));
}else{
   header('HTTP/1.1 200 OK');
   header('content-length:'.$fileSize);//返回文件大小
}

// 開啓緩衝區
ob_start();
// 分段讀取文件
while (!feof($fp)) {
  //設置文件最長執行時間
  set_time_limit(0);
  $chunk_size = 1024 * 1024 * 10; // 10MB
  echo fread($fp, $chunk_size);
  ob_flush(); // 刷新PHP緩衝區到Web服務器
  flush(); // 刷新Web服務器緩衝區到瀏覽器
  //sleep(1); // 每1秒 下載 10 MB
}
// 關閉緩衝區
ob_end_clean();
($fp != null) && fclose($fp);

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章