How to Create ZIP Archive with Files And Download it in Laravel

Tutorial last revisioned on August 11, 2022 with Laravel 9

If you need your users to be able to download multiple files at once, it's better to create one archive and let them download it. Here's how to do it in Laravel.

In fact, it's less about Laravel and more about PHP, we will be using ZipArchive class that existed since PHP 5.2. To use that, make sure your php.ini has enabled extension called ext-zip.


Task 1. Archive user's invoice from storage/invoices/aaa001.pdf

Here's the code:

$zip_file = 'invoices.zip'; // Name of our archive to download

// Initializing PHP class
$zip = new \ZipArchive();
$zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

$invoice_file = 'invoices/aaa001.pdf';

// Adding file: second parameter is what will the path inside of the archive
// So it will create another folder called "storage/" inside ZIP, and put the file there.
$zip->addFile(storage_path($invoice_file), $invoice_file);
$zip->close();

// We return the file immediately after download
return response()->download($zip_file);

That's it, nothing too difficult, right?


Task 2. Archive all files in a folder storage/invoices

Nothing changes from Laravel side, we will just add some more plain PHP code for iterating the files.

$zip_file = 'invoices.zip';
$zip = new \ZipArchive();
$zip->open($zip_file, \ZipArchive::CREATE | \ZipArchive::OVERWRITE);

$path = storage_path('invoices');
$files = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path));
foreach ($files as $name => $file)
{
    // We're skipping all subfolders
    if (!$file->isDir()) {
        $filePath     = $file->getRealPath();

        // extracting filename with substr/strlen
        $relativePath = 'invoices/' . substr($filePath, strlen($path) + 1);

        $zip->addFile($filePath, $relativePath);
    }
}
$zip->close();
return response()->download($zip_file);

We're done here. You see, you don't need any Laravel packages to achieve this.

Saying that, if you use Spatie Media Library, they have a special class for it, called MediaStream.

avatar

is there any way to rearrange the downloaded files in an order like i have pdf files of items,equipment reports,specification reports they are sorting alpha batically but i want to sort as item on top then specification and equipments reports. Thanks

avatar

There's no way to sort files in any other way than alphabetical order. That's how the filesystem works (for example, file explorer/finder will automatically sort the files by name).

The best you can do here is group them by folders. But even then - they will not be in some kind of order, unless you prefix them with 00, 01, 02 and so on.

avatar

hey Povilas

Im using the same code to zip some files insode a folder and download the zip file. However, the zip file generated on the server opens fine. But the one dowbloaded cannot open. in fact I get a message saying that "zip file is in a nonsupported format".

Have you faced this issue with zip files before?

Much appreciated

Bilal

avatar

I have never seen this issue personally... Used this exact method a lot in my projects and it just worked.

Maybe something changed with chrome/browser downloads where you need to confirm the file download if there's an SSL issue?

avatar

hey Thanks for your reply. im testing locally. The file genearted opens fine inside thr Laravel app. but when downloaded its not.

avatar

Hello @Modestas, Just to confirm, this code works perfectly when uploaded to Laravel Forge. Most probably, something wrong on my local environment using Laravel Sail. Maybe an an extension needs to be enabled.

Thanks again for your support. Appreciate it. Bilal

Like our articles?

Become a Premium Member for $129/year or $29/month
What else you will get:
  • 58 courses (1056 lessons, total 44 h 09 min)
  • 78 long-form tutorials (one new every week)
  • access to project repositories
  • access to private Discord

Recent Premium Tutorials