Well, this scenario probably can drive you crazy. Say, you have a Laravel web system, and all your photo uploads to the system are saved in another host. In this case, let’s take Amazon S3 bucket.
You may wanna find out a way to download an entire folder with files inside, zipped, with a single click. That can be a fair request from your client.
So, today I’m going to show you how to do that.
We do this like this, first files are download to the host of our system, then they are zipped and downloaded to the local computer of whoever download. That’s the plan!
first of all, I’m gonna create a method in a specific controller.
public function downloadAlbum($id){
}
Then I’m gonna create the logic to get all the photos from a specific album.
public function downloadAlbum($id){
$photos = Photos::where('album_id', $id)->get();
}
Perfect! Now I have all the photos of the particular album.
Then, I’m using PHP’s ZipArchive class to create the zip file.
public function downloadAlbum($id){
$photos = Photos::where('album_id', $id)->get();
$zip = new \ZipArchive();
$zip->open('/var/www/html/mysite/uploads/zip/myalbum'.time().'.zip', \ZipArchive::CREATE);
}
What the above code does is, it creates an empty ZIP Archive file with the file name similar to myalbum35635353455.zip.
Now we need to download photos from Amazon S3, and put them in the Zip Archive we’ve just created.
For that, I’m using a foreach loop.
public function downloadAlbum($id){
$photos = Photos::where('album_id', $id)->get();
$zip = new \ZipArchive();
$zip->open('/var/www/html/mysite/uploads/zip/myalbum'.time().'.zip', \ZipArchive::CREATE);
foreach ($photos as $photo){
$zip->addFromString($photo->image, file_get_contents("http://mysite.s3-ap-southeast-1.amazonaws.com/albums/".$id."/".$photo->image));
}
}
Well, that’s pretty much it. Now, the images are downloaded from the S3 bucket and put them inside the Zip Archive.
Now we need to download this Zip file. And don’t forget to close the Zip object after the loop.
public function downloadAlbum($id){
$photos = Photos::where('album_id', $id)->get();
$zip = new \ZipArchive();
$zip->open('/var/www/html/mysite/uploads/zip/myalbum'.time().'.zip', \ZipArchive::CREATE);
foreach ($photos as $photo){
$zip->addFromString($photo->image, file_get_contents("http://mysite.s3-ap-southeast-1.amazonaws.com/albums/".$id."/".$photo->image));
}
$zip->close();
}
Completed method
Finally, send the Zip file to the web browser as a download
public function downloadAlbum($id){
$photos = Photos::where('album_id', $id)->get();
$zip = new \ZipArchive();
$zip->open('/var/www/html/mysite/uploads/zip/myalbum'.time().'.zip', \ZipArchive::CREATE);
foreach ($photos as $photo){
$zip->addFromString($photo->image, file_get_contents("http://mysite.s3-ap-southeast-1.amazonaws.com/albums/".$id."/".$photo->image));
}
$zip->close();
header('Content-disposition: attachment; filename='.$album->name.'.zip');
header('Content-type: application/zip');
readfile('/var/www/html/mysite/uploads/zip/myalbum'.time().'.zip');
}
That’s it! Now you can add a route to this method and call it on specific album to download.

December 28, 2020 at 7:00 am
Thank you! it has been wery useful for me.