Readfile reads 0 bytes from large file?

痴心易碎 提交于 2019-12-02 09:55:58
Dubas

PHP readfile uses the page buffer to store the file before send it. If it fails due to insufficient memory it does not throw a memory error only fail.

Ensure that the page that performing the download is not using page buffer( http://us1.php.net/manual/es/ref.outcontrol.php)

Also is better for big files to use fopen an fread to read the file and put the content. Also with fread you can make some code to allow the download to be resumed.

Here there's a good example: Resumable downloads when using PHP to send the file?


To disable ouput buffering you should try to clean and end buffer before process start with ob_end_clean() or disable the output buffering using ini_set('output_buffering', 0);


In the readfile documentation there's an example about how to use fread for long files instead of readfile:

http://ca2.php.net/manual/en/function.readfile.php#48683

function readfile_chunked($filename,$retbytes=true) {
   $chunksize = 1*(1024*1024); // how many bytes per chunk
   $buffer = '';
   $cnt =0;
   $handle = fopen($filename, 'rb');
   if ($handle === false) {
       return false;
   }
   while (!feof($handle)) {
       $buffer = fread($handle, $chunksize);
       echo $buffer;
       ob_flush();
       flush();
       if ($retbytes) {
           $cnt += strlen($buffer);
       }
   }
       $status = fclose($handle);
   if ($retbytes && $status) {
       return $cnt; // return num. bytes delivered like readfile() does.
   }
   return $status;

} 

Also there's an example with partial download support in the same page:

function smartReadFile($location, $filename, $mimeType='application/octet-stream') { 
  if(!file_exists($location)) { 
    header ("HTTP/1.0 404 Not Found");
    return;
  }

  $size=filesize($location);
  $time=date('r',filemtime($location));

  $fm=@fopen($location,'rb');
  if(!$fm) { 
    header ("HTTP/1.0 505 Internal server error");
    return;
  }

  $begin=0;
  $end=$size;

  if(isset($_SERVER['HTTP_RANGE'])) { 
     if(preg_match('/bytes=\h*(\d+)-(\d*)[\D.*]?/i', $_SERVER['HTTP_RANGE'], $matches)){ 
      $begin=intval($matches[0]);
      if(!empty($matches[1])){ $end=intval($matches[1]); }
    }
  }

  if($begin>0||$end<$size){
    header('HTTP/1.0 206 Partial Content');
  }else{
    header('HTTP/1.0 200 OK'); 
  }

  header("Content-Type: $mimeType");
  header('Cache-Control: public, must-revalidate, max-age=0');
  header('Pragma: no-cache'); 
  header('Accept-Ranges: bytes');
  header('Content-Length:'.($end-$begin));
  header("Content-Range: bytes $begin-$end/$size");
  header("Content-Disposition: inline; filename=$filename");
  header("Content-Transfer-Encoding: binary\n");
  header("Last-Modified: $time");
  header('Connection: close'); 

  $cur=$begin;
  fseek($fm,$begin,0);

  while(!feof($fm)&&$cur<$end&&(connection_status()==0)) { 
    print fread($fm,min(1024*16,$end-$cur));
    $cur+=1024*16;
  }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!