Create a script to compress folders in ZIP with PHP

Try this simple script to automate folder compression, it’s very easy to implement!

December 7, 2021

There are many tools available to compress files in zip format: you can use either operating system programs or terminal mode, but based on some of my own use cases I’ve noticed that it’s quite inconvenient to keep right-clicking to compress.

What if I’m on a Mac and I don’t want to include .DS_Store files, or if I’m developing and I need to compress a folder that has a node_module, vendor, .idea, etc.? I have to delete these folders by hand just to compress the folder I need. A nuisance, in short. 

To avoid all this, I invite you to use this super practical script. And like any recipe, let’s first see what what we’re going to need:

First we’re going to create the folder of our project:

$ mkdir folder-compressor && cd folder-compressor

Now let’s initialize a PHP project using composer to manage the packages we will install, this is very similar to NPM for NodeJS.

$ composer init

For each question that pops up we simply hit enter and once the process is finished we should have something similar to this:

{
"name": "michaelcardoza/folder-compressor",
"authors": [
{
"name": "Michael Cardoza",
"email": "mc.michaelcardoza@gmail.com"
}
],
"require": {
"nelexa/zip": "^4.0"
}
}

Now let’s install the package we’ll need.

$ composer require nelexa/zip

Now we’re going to create a file as an entry point.

First, we import the autoload.php file in order to load and manage the required php packages or libraries. Then, we’re going to gather the resources we’re going to use. In this case, we will use the resources with the namespace PhpZip from the package we installed.

// compressor.php<?php

require_once
__DIR__ . '/vendor/autoload.php';

use PhpZip\ZipFile;
use PhpZip\Exception\ZipException;
use PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator;

Once the resources we are going to use are ready, we’re going to set our first parameters and we’re going to save the instance of the ZipFile class declaration in one of them.

// compressor.php 
<?php //... $zipFile = new ZipFile();

// Nombres de las carpetas a comprimir
$folders = ['folder-1','folder-2'];

// Archivos o Carpetas que serán ignoradas
$ignoreFiles = ['node_modules/', 'src/', '.idea/', '.git/'];

// Folder donde se guardaran los archivos ZIP
$destFolder = 'zips';

Ok, now we are going to build the logics to compress the folders, but first we’ll create a resources folder to store the folder-1 and folder-2 that are just demos.

// compressor.php<?php// ...try {
if (!file_exists($destFolder) && !is_dir($destFolder)) {
mkdir($destFolder);
} foreach ( $folders as $folder ) {
$directoryIterator = new RecursiveDirectoryIterator(__DIR__ . "/resources/{$folder}");
$ignoreIterator = new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles); $zipFile
->addFilesFromIterator($ignoreIterator)
->saveAsFile("{$destFolder}/{$folder}.zip")
->close();
} echo "\\n @ --- Compressed folders --- 😎 ! \\n";
} catch ( ZipException $e ) {
echo $e;
}

The complete File should look like this:

<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpZip\\ZipFile;
use PhpZip\\Exception\\ZipException;
use PhpZip\\Util\\Iterator\\IgnoreFilesRecursiveFilterIterator;
$zipFile = new ZipFile();
// Nombres de las carpetas a comprimir
$folders = ['folder-1','folder-2'];
// Archivos o Carpetas que serán ignoradas
$ignoreFiles = ['node_modules/', 'src/', '.idea/', '.git/'];
// Folder donde se guardaran los archivos ZIP
$destFolder = 'zips';
try {
    if (!file_exists($destFolder) && !is_dir($destFolder)) {
        mkdir($destFolder);
    }
    foreach ( $folders as $folder ) {
        $directoryIterator = new RecursiveDirectoryIterator(__DIR__ . "/resources/{$folder}");
        $ignoreIterator = new IgnoreFilesRecursiveFilterIterator($directoryIterator, $ignoreFiles);
        $zipFile
            ->addFilesFromIterator($ignoreIterator)
            ->saveAsFile("{$destFolder}/{$folder}.zip")
            ->close();
    }
    echo "\\n @ --- Compressed folders --- 😎 ! \\n";
} catch ( ZipException $e ) {
    echo $e;
}

Up to this point you should have an automatically created zips folder with the folders compressed in ZIP format.

// Ejemplo de la ejecución en mi terminal
➜  folder-compressor php compressor.php
@ --- Compressed folders --- 😎 !

Summary:

As you will see, this script is very small and you can include many other options. In addition, we can convert it into a global 📦 package for our project and include it in via composer. 

I hope you find it helpful!

If you need more information, here is my repo.