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

 

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