Jump to content

[SOLVED] Cannot download multiple files


T-Bird

Recommended Posts

I have files that need to be downloaded only if the user has the correct password, thus I'm using the standard readfile() based download method as seen in example 1 of php.net's readfile manual.

 

if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit;
}

 

The files I'm trying to transfer are on average 80MB zip files stored on the same box that is running the scripts.

 

I have two problems which I think are related... but may not be.

 

a) The user submits the password and it takes approximately a minute for the save dialogue box to appear.  PHP logs a timeout error, but the file downloads fine.

 

b) With files less than 60MB I can download several files at a time no sweat.  With files over 60MB in size I can only download one file at a time.  Anyone who tries to download the file while a transfer is in progress gets an empty placeholder file.

 

I tried switching to a chunked transfer method.  I got a code out of the comments on the php.net site that seemed promising and tried it.

 

function readfile_chunked($filename,$retbytes=true) {
   $chunksize = 1*(1024*1024); // how many bytes per chunk
   $buffer = '';
   $cnt =0;
   // $handle = fopen($filename, 'rb');
   $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;

} 

 

This solved problem-a as data immediately started to transfer to the browser.  I didn't get to test if it solved problem-b because after aprox 25-30 seconds php again (understandably) logged the timeout error and the transfer died.

 

Any clue why php is refusing to allow multiple downloads on code a?  Is there a way I can adjust PHP's timeout for only ONE page so that I can use code B without having all my pages use an ugly 1hour timeout?

 

Any other suggestions?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.