简体   繁体   中英

How to download multiple large files with php?

I had tried to download multiple large files with the zip php extension but I wasn't successful, because the server has always timed out.

$revfiles = $_POST['file'];
if(empty($revfiles))
{
  echo("You didn't select any file.");
}
else
{
  $zip = new ZipArchive();
  $filename = $_SERVER['DOCUMENT_ROOT'] . "/tmp/test70.zip";
  if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
    exit("cannot open <$filename>\n");
  }
  $N = count($revfiles);
  for($i=0; $i < $N; $i++)
  {
    if($zip->addFile($_SERVER['DOCUMENT_ROOT'] . "/" . $revfiles[$i], strrchr($revfiles[$i], "/"))!==TRUE){
      //echo("ERROR");
    }
  }
  $zip->close();    

  header("Content-type: application/zip"); 
  header("Content-Disposition: attachment; filename=test70.zip"); 
  header("Pragma: no-cache"); 
  header("Expires: 0"); 
  readfile("$filename");
  exit;
}

[30-Dec-2015 12:32:17 Europe/Berlin] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /.../file.php on line 37

After I had disabled the time limit for this script, I got this error:

[30-Dec-2015 16:38:29 Europe/Berlin] PHP Fatal error:  Allowed memory size of 524288000 bytes exhausted (tried to allocate 660656128 bytes) in /.../file.php on line 43

Does somebody know another way to download multiple large files with php ?

It looks like you need to change the memory and file upload size limits as well as your script execution time. All can be changed in your php.ini file, though I would change the max execution time script by script rather than changing it for all PHP requests.

MAX EXECUTION TIME

Changing the execution time can be done in two ways (within a script)...

1) By placing the below line at the top of your script. This will allow the script to run indefinitely. If you'd like more granular control of how long each file has to upload, go with the second suggestion.

set_time_limit(0);

2) Use that same line in your loop instead of at the beginning of the script, but change the number of seconds from 0 to however long you want to give each file to download. This works because set_time_limit() resets the execution time to zero each time that it's called.

So if you want to allow each file to have 30 seconds, your loop will look something like...

for($i=0; $i < $N; $i++)
{
    set_time_limit(30);
    if($zip->addFile($_SERVER['DOCUMENT_ROOT'] . "/" . $revfiles[$i], strrchr($revfiles[$i], "/"))!==TRUE){
        //echo("ERROR");
    }
}

MEMORY & MAX FILE SIZES

There are three settings that you should change:

  • upload_max_filesize
  • post_max_size
  • memory_limit

If you are using a web host that doesn't give you access to the php.ini file then you can change these in your script or in a htaccess file (adjust the values for your needs)...

PHP File

ini_set('upload_max_filesize', '64M');
ini_set('post_max_size', '64M');
ini_set('memory_limit', '32M');

.htaccess File:

<IfModule mod_php5.c>
   php_value upload_max_filesize 64M
   php_value post_max_size 64M
   php_value memory_limit 32M
</IfModule>

If you do have access to your php.ini file, simply change the settings there!

You'll want to stream the file out in chunks. Here's a SO post on this: Download File to server from URL

file_put_contents("Tmpfile.zip", fopen("http://someurl/file.zip", 'r'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM