Zip files are used to create lossless data compression and store multiple files folder in single file. In laravel create zip of file or nested folder laravel can be archived by ZipArchive library,its gives easy to use flexibilities to developers so they can easily integrate the Zip creation activity in the project. So in this article i will show you to create zip of file or folder in laravel of multiple files and folder in single file then easily download or store at server path.
In this article i will use PHP ZipArchive library to create the zip. This library has several methods to open, create , extract, add, setPath, delete and many more. But in this topic we will cover creating the zip file and add the files and folder to the zip.
In this example we will create a simple example to add the files and nested folder to zip file in laravel . For this we will create a controller, files and zip.
Let’s start Create Zip of File or nested Folder in Laravel with simple step by step
Step 1: Create a fresh laravel project
Open a terminal window and type below command to create a new project
composer create-project --prefer-dist laravel/laravel blog
You can also read this to start with new project
Step 2 : Create controller
Let’s create a controller and add method createZip
php artisan make:controller ZipController
and add the below code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use ZipArchive;
class ZipController extends Controller
{
function createZip(){
//save to server
$fileName = time().rand(111111111,9999999999).'_invoice.zip';
$destinationPath= '/uploads/zip';
$storageDestinationPath= storage_path("app$destinationPath");
if (!\File::exists( $storageDestinationPath)) {
\File::makeDirectory($storageDestinationPath, 0755, true);
}
$zip = (new ZipArchive());
$isOpened = $zip->open($storageDestinationPath."/".$fileName, ZipArchive::CREATE | \ZipArchive::OVERWRITE);
if($isOpened === TRUE){
$this->addToZip(
$zip,[
storage_path("app/uploads/images/16526291274723877395.jpg"),
storage_path("app/uploads/images/thumbs"),
storage_path("app/uploads/images/16526317155446630681.jpeg"),
storage_path("app/uploads/images/thumbs/50x50"),
],
"invoices"
);
$zip->close();
return response()->download($storageDestinationPath."/".$fileName,"invoices.zip");
}
else{
return response()->html("Unbale to create/open zip");
}
}
function createZipInFLy(){
//in the fly without storing to server
$fileName = @tempnam("tmp", "zip");
$zip = (new ZipArchive());
$isOpened = $zip->open($$fileName, ZipArchive::CREATE | \ZipArchive::OVERWRITE);
if($isOpened === TRUE){
$this->addToZip(
$zip,[
storage_path("app/uploads/images/16526291274723877395.jpg"),
storage_path("app/uploads/images/thumbs"),
storage_path("app/uploads/images/16526317155446630681.jpeg"),
storage_path("app/uploads/images/thumbs/50x50"),
],
"invoices"
);
$zip->close();
return response()->download($fileName,"invoices.zip");
}
else{
return response("Unbale to create/open zip");
}
}
function addToZip($zip,$filesArray,$fileName=''){
$dir='';
if($fileName!=''){
$fileName = str_replace(".zip","",$fileName);
$zip->addEmptyDir($fileName);
$dir=$fileName."/";
}
foreach($filesArray as $k=>$path){
$isFile = \File::isFile($path);
if($isFile){
$file = new \SplFileInfo($path);
$zip->addFile($file->getPathname(),$dir.$file->getFilename());
}
else{
$it = new \RecursiveDirectoryIterator($path);
$repalcer=dirname($it->getPath());;
foreach(new \RecursiveIteratorIterator($it) as $file)
{
if(!$file->isDir()){
$zip->addFile($file->getPathname(),"$dir".str_replace($repalcer."/","",$file->getPathname()));
}
}
}
}
}
}
In above code First of all we are checking the directory is exist or not then if not available then we are creating the directory at the location.
Then using ZipArchive library we are creating the zip file and opened successfully then we have created another method which is addToZip
to handle the logic to add the multiple files and folder to zip file. it accepts ZipArchive
object, second array of files and folder and third name of zip file as below
function addToZip($zip,$filesArray,$fileName=''){
$dir='';
if($fileName!=''){
$fileName = str_replace(".zip","",$fileName);
$zip->addEmptyDir($fileName);
$dir=$fileName."/";
}
foreach($filesArray as $k=>$path){
$isFile = \File::isFile($path);
if($isFile){
$file = new \SplFileInfo($path);
$zip->addFile($file->getPathname(),$dir.$file->getFilename());
}
else{
$it = new \RecursiveDirectoryIterator($path);
$repalcer=dirname($it->getPath());;
foreach(new \RecursiveIteratorIterator($it) as $file)
{
if(!$file->isDir()){
$zip->addFile($file->getPathname(),"$dir".str_replace($repalcer."/","",$file->getPathname()));
}
}
}
}
}
Here if filename is provided the we are first creating a directory with same name then checking the file type if its a file then adding it to zip else directory then we are using RecursiveDirectoryIterator
to process the nested folder to add into the zip.
Create and Download zip file in the fly
By creating the file in temp folder we can download the zip without saving to the server for long time so we have create this method
function createZipInFLy(){
//in the fly without storing to server
$fileName = @tempnam("tmp", "zip");
$zip = (new ZipArchive());
$isOpened = $zip->open($$fileName, ZipArchive::CREATE | \ZipArchive::OVERWRITE);
if($isOpened === TRUE){
$this->addToZip(
$zip,[
storage_path("app/uploads/images/16526291274723877395.jpg"),
storage_path("app/uploads/images/thumbs"),
storage_path("app/uploads/images/16526317155446630681.jpeg"),
storage_path("app/uploads/images/thumbs/50x50"),
],
"invoices"
);
$zip->close();
return response()->download($fileName,"invoices.zip");
}
else{
return response()->html("Unbale to create/open zip");
}
}
Step 3: Create two routes in routes/web.php
One route for save the zip to the server as well download and other to download in the fly without saving to server.
routes/web.php
<?php
use App\Http\Controllers\ZipController;
use Illuminate\Support\Facades\Route;
Route::get("/create-zip",[ZipController::class,"createZip"]);
Route::get("/create-zip-fly",[ZipController::class,"createZipInFLy"]);
I
Results Screenshot:
I hope it will help you to implement to create zip file with files and folders. you can also read article to How to Import or Convert Excel/CSV to HTML in laravel 8 / 9?