Make Multiple Files to Force-Download

Download multiple files with a single action

HTTP does not support more than one file download at once.

There are two solutions:

  • Open x amount of windows to initiate the file downloads (this would be done with JavaScript)
  • preferred solution create a script to zip the files

How can I let a user download multiple files when a button is clicked?

The best way to do this is to have your files zipped and link to that:

The other solution can be found here: How to make a link open multiple pages when clicked

Which states the following:

HTML:

<a href="#" class="yourlink">Download</a>

JS:

$('a.yourlink').click(function(e) {
e.preventDefault();
window.open('mysite.com/file1');
window.open('mysite.com/file2');
window.open('mysite.com/file3');
});

Having said this, I would still go with zipping the file, as this implementation requires JavaScript and can also sometimes be blocked as popups.

Force download of multiple files with header() in php

You can only transfer one file from server side at a time. Typical workarounds are:

  1. tar/zip them up into one file on server side.
  2. use javascript to window.open multiple files for download.

PHP multiple file download

You can't. It's not a PHP limitation, it's an HTTP/Web-Browser limitation. HTTP doesn't provide a mechanism for sending multiple files over one request.

You could, however, have some PHP script that generates multiple iframes, which would initiate one download each, and fake it that way.

How in JS to download more than 10 files in browser including Firefox

Instead of downloading multiple files, the best is probably to pack them all in a single file.
You can for instance generate a zip file from all these files.

Since you stated that server-side solution was not an option for you, but that all your files are hosted on your domain, then I can propose you to first fetch through AJAX all your files (since these are images already loaded on the page, they won't even need to be actually downloaded again, but only gathered from cache) and then build your zip file on the front-end.

// all images are from wikimediaconst urls = ['/3/3b/Hulda_Klagers_house_and_lawn.jpg/320px-Hulda_Klagers_house_and_lawn.jpg', '/1/15/P%C3%A8re-Lachaise_-_Division_79_-_Floriot_02.jpg/320px-P%C3%A8re-Lachaise_-_Division_79_-_Floriot_02.jpg', '/a/a6/V37-20180910-055_%2845088120261%29.jpg/320px-V37-20180910-055_%2845088120261%29.jpg', '/2/2b/MormantulLuiAmzaPellea_%284%29.JPG/360px-MormantulLuiAmzaPellea_%284%29.JPG', '/f/f8/Launch_of_LAWRENCE_LCCN2014710971.tif/lossy-page1-174px-Launch_of_LAWRENCE_LCCN2014710971.tif.jpg'].map((url) => 'https://upload.wikimedia.org/wikipedia/commons/thumb' + url);
fetchBlobs(urls) .then(pack) .then((zipFile) => dl.href = URL.createObjectURL(zipFile));
function fetchBlobs(urls) { return Promise.all( urls.map((url) => fetch(url) .then((resp) => resp.blob()) .then((blob) => { // store the file name blob.name = url.slice(url.lastIndexOf('/') + 1) return blob; }) ) );}function pack(blobs) { const zip = new JSZip(); const folder = zip.folder('my_images'); blobs.forEach((blob) => folder.file(blob.name, blob)); return zip.generateAsync({type : "blob"});}
<!-- using JSZip library https://stuk.github.io/jszip/ --><script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.2.0/jszip.min.js"></script><a id="dl" download="images.zip">download</a>

Download multiple files as a zip-file using php

You can use the ZipArchive class to create a ZIP file and stream it to the client. Something like:

$files = array('readme.txt', 'test.html', 'image.gif');
$zipname = 'file.zip';
$zip = new ZipArchive;
$zip->open($zipname, ZipArchive::CREATE);
foreach ($files as $file) {
$zip->addFile($file);
}
$zip->close();

and to stream it:

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$zipname);
header('Content-Length: ' . filesize($zipname));
readfile($zipname);

The second line forces the browser to present a download box to the user and prompts the name filename.zip. The third line is optional but certain (mainly older) browsers have issues in certain cases without the content size being specified.

Can I force download mutiple files or a zip file?

That's not possible, simply because neither the HTTP protocol nor any browser do support something like that, it's not a CakePHP thing.

If you need to serve multiple files with a single request then you'll have to put them in some kind of archive, however that also isn't directly related to CakePHP as it doesn't ship with a ZIP library or similar, it's all about PHP.

I don't think there's any need at this point to explain how to ZIP files with PHP, as this is something that is explained on every corner of the internet.

  • http://php.net/zip
  • https://stackoverflow.com/search?q=%5Bphp%5D+zip

Once you've zipped your files, either pass the zipped data to CakeResponse::body() as a string like you're already doing (not recommended for large archives as it will blow up the memory usage), or temporarily store the ZIP file on disk and use CakeResponse::file().

http://book.cakephp.org/2.0/en/controllers/request-response.html#sending-files



Related Topics



Leave a reply



Submit