Lock all files in directories and force download

The following code works on my site. The only problem I am connected with is that it makes a zip file on the server and then loads users.

I would like to know what should I do so that the zip file is generated on the fly without first being flushed to the server disk. I would also like the user to be able to pause / resume the download.

//function for zip function zipFilesAndDownload($file_names,$archive_file_name,$file_path) { //create the object $zip = new ZipArchive(); //create the file and throw the error if unsuccessful if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE )!==TRUE) { exit("cannot open <$archive_file_name>\n"); } //add each files of $file_name array to archive foreach($file_names as $files) { $zip->addFile($file_path.str_replace('./','',$files),translit($files).".mp3"); } $zip->close(); //then send the headers to foce download the zip file header("Content-type: application/zip"); header("Content-Disposition: attachment; filename=$archive_file_name"); header("Pragma: no-cache"); header("Expires: 0"); readfile("$archive_file_name"); exit; } 
+6
source share
1 answer

You mentioned three requirements:

  • zip is available for download on fly - I assume that by this you mean β€œa zip file is created on the fly. This is already happening. In fact, this is what your script does, it's raison d'etre, if you want .
  • zip file should not be created on server - you need to create a file on the server, even if it is temporary, because the Zip extension works this way. You can delete it after the user has downloaded it (just add unlink($archive_file_name); to the line before exit; ).
  • user can also resume it if paused - This requirement is (mostly) incompatible with zip file should not be created on server . Renewable downloads can be implemented in PHP, but it is quite difficult to do and requires access to the Range: request header, which not every server will allow you to have. In addition, you will need to generate the entire file even for a partial request, because you deleted it from the server. Apache has a resilient download implementation, but it requires (AFAIK) that the file be static on the hard drive and be requested directly. This would mean that deleting the file after downloading it (at the end of the PHP script) will violate renewal.

Reading between the lines, I suspect that the problem you are facing is that your server’s hard drive space has been consumed by all the Zip archives that you create and not delete. The solution to this problem (although it allows you to resume downloading) is to implement some form of TTL verification on the server and periodically delete files that are older, for example, 1 day. You can do this with the cron job, or run a check when creating a new archive.

At the moment, your code does not indicate where zip files will be generated, and this is what you will need to do. Here is an example assuming that your script is in the root directory of your site and that there is a directory called zips in the root directory of your site.

Main stream:

  • Scroll through the / zips directory and delete all files older than 1 day.
  • Create a new archive in the / zips directory
  • Redirect the user to the path of this static file.
 function zipFilesAndDownload($file_names, $archive_file_name, $file_path) { // Archive directory $archiveDir = 'zips'; // Time-to-live $archiveTTL = 86400; // 1 day // Files to ignore $ignoreFiles = array('.', '..'); // Loop the storage directory and delete old files if ($dp = opendir($archiveDir)) { while ($file = readdir($dp)) { if (!in_array($file, $ignoreFiles) && filectime("$archiveDir/$file") < (time() - $archiveTTL)) { unlink("$archiveDir/$file"); } } } // Re-format the file name $archive_file_name = "$archiveDir/".basename($archive_file_name); // Create the object $zip = new ZipArchive(); // Create the file and throw the error if unsuccessful if ($zip->open($archive_file_name, ZIPARCHIVE::CREATE) !== TRUE) { exit("Cannot open '$archive_file_name'\n"); } // Add each file of $file_name array to archive foreach($file_names as $file) { $zip->addFile($file_path.str_replace('./', '', $file), translit($files).".mp3"); } $zip->close(); // Then send the headers to redirect to the ZIP file header("HTTP/1.1 303 See Other"); // 303 is technically correct for this type of redirect header("Location: http://{$_SERVER['HTTP_HOST']}/$archive_file_name"); exit; } 
+6
source

Source: https://habr.com/ru/post/903087/


All Articles