Add Files & Folders In PHP ZIP (Basics, Entire Folder, Recursive)

Welcome to a quick tutorial on how to add files and folders with PHP Zip. So you have a project that needs some zip archive action, and no idea where to start?

We can add files and folders to a zip file in PHP using the ZipArchive extension:

  • $zip = new ZipArchive();
  • $zip->open("archive.zip", ZipArchive::CREATE);
  • $zip->addFile("target.file", "name-in-zip.file");
  • $zip->addEmptyDir("folder");
  • $zip->close();

That should cover the basics, but adding entire folders is a different story – Read on for more examples!

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

HOW TO ADD FILES & FOLDERS WITH PHP ZIP

All right, let us now get into the examples of the various ways to add files and folders into a zip archive in PHP.

 

TUTORIAL VIDEO

 

1) BASICS – ADDING FILES & FOLDERS

1-basic.php
<?php 
// (A) NEW ZIP ARCHIVE OBJECT
$zip = new ZipArchive();
$zipfile = "demoA.zip";

// (B) OPEN/CREATE ZIP FILE
if ($zip->open($zipfile, ZipArchive::CREATE) === true) {
  // (B1) ADD FILE
  echo $zip->addFile("readme.txt", "filename-in-zip.txt")
   ? "File added to zip archive" : "Error adding file to zip archive" ;
  
  // (B2) ADD FOLDER
  echo $zip->addEmptyDir("folder")
   ? "Folder added to zip archive" : "Error adding folder to zip archive" ;
  
  // (B3) CLOSE ZIP
  echo $zip->close()
   ? "Zip archive closed" : "Error closing zip archive" ;
}

// (C) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; }

Yes, this is kind of an “expanded version” of the introduction – We start by creating a $zip = new ZipArchive() object, then there are only 4 basic zip functions that you should know.

  • open(FILE, MODE) This opens a zip file, but take extra note of the possible modes:
    • ZipArchive::CREATE – Creates a new zip archive if not found.
    • ZipArchive::OVERWRITE – Overwrite if there is an existing zip archive.
    • ZipArchive::EXCL – The safer way, which will return an error if there is an existing zip archive.
    • ZipArchive::RDONLY – Readonly.
    • ZipArchive::CHECKONS – Checks the zip archive, throws an error if the checksum fails.
  • addFile(TARGET, FILENAME IN ZIP) Self-explanatory, add a file into the zip archive.
  • addEmptyDir(FOLDER NAME) Self-explanatory again, add a folder inside the zip archive.
  • close() Necessary, properly close, and save the zip file.

 

 

2) APPENDING FILES INTO A FOLDER IN THE ZIP ARCHIVE

2-append.php
<?php 
// (A) LOAD EXISTING ZIP ARCHIVE
$zip = new ZipArchive();
$zipfile = "demoA.zip";
if ($zip->open($zipfile, ZipArchive::CREATE) === true) {
  // (B) APPEND FILE INTO ZIP
  echo $zip->addFile("1-basic.php", "1-basic.php")
   ? "File added to zip archive" : "Error adding file to zip archive" ;

  // (C) ADD FILE INTO FOLDER IN ZIP
  echo $zip->addFile("2-append.php", "folder/2-append.php")
   ? "File added to zip archive" : "Error adding file to zip archive" ;

  // (D) CLOSE ZIP
  echo $zip->close()
   ? "Zip archive closed" : "Error closing zip archive" ;
}

// (E) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; }

To append more files into an existing zip archive, we simply open it again and use the addFile() function; To add the file into a folder within the zip archive, we only have to specify it accordingly – addFile(TARGET.FILE, FOLDER-IN-ZIP/SAVE.FILE).

 

 

3) FROM STRING TO ZIP FILE

3-string.php
<?php 
// (A) OPEN/CREATE ZIP FILE
$zip = new ZipArchive();
$zipfile = "demoA.zip";
if ($zip->open($zipfile, ZipArchive::CREATE) === true) {
  // (B) ADD FROM STRING
  echo $zip->addFromString("string.txt", "This is a string!")
   ? "File added to zip archive" : "Error adding file to zip archive" ;
}

// (C) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; }

Just a convenience for you guys who want to archive logs or any content – Use the addFromString() function to save a string into a zip file.

 

 

4) ADD ENTIRE FOLDER INTO ZIP ARCHIVE (USING GLOB)

4-folder-glob.php
<?php 
// (A) NEW ZIP ARCHIVE OBJECT
$zip = new ZipArchive();
$zipfile = "demoB.zip";
$tozip = __DIR__ . "/test/";

// (B) OPEN/CREATE ZIP FILE
if ($zip->open($zipfile, ZipArchive::CREATE) === true) {
  // (B1) ADD ENTIRE FOLDER
  // add all jpg png gif files in "/test/" into the "inside/" folder of the zip archive
  echo $zip->addGlob($tozip . "*.{jpg,png,gif}", GLOB_BRACE, [
    "add_path" => "inside/",
    "remove_all_path" => true
  ]) ? "Folder added to zip" : "Error adding folder to zip" ;

  // (B2) CLOSE ZIP
  echo $zip->close()
   ? "Zip archive closed" : "Error closing zip archive" ;
}

// (C) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; }

PHP comes with a very handy glob() function to filter out files/folders in the system. There is also a addGlob() function that we can use in the zip archive – To add an entire folder or filter out certain file extensions only.

Take note though – This will not “dig” into the sub-folders of the specified target folder.

 

 

5) ADD ENTIRE FOLDER INTO ZIP ARCHIVE (USING PATTERN)

5-folder-pattern.php
<?php 
// (A) NEW ZIP ARCHIVE OBJECT
$zip = new ZipArchive();
$zipfile = "demoC.zip";
$tozip = __DIR__ . "/test/";

// (B) OPEN/CREATE ZIP FILE
if ($zip->open($zipfile, ZipArchive::CREATE) === true) {
  // (B1) ADD ENTIRE FOLDER
  // add all php txt files in "/test/" into the "inside/" folder of the zip archive
  echo $zip->addPattern("/\.(?:php|txt)$/", $tozip, [
    "add_path" => "inside/",
    "remove_all_path" => true
  ]) ? "Folder added to zip" : "Error adding folder to zip" ;

  // (B2) CLOSE ZIP
  echo $zip->close()
   ? "Zip archive closed" : "Error closing zip archive" ;
}

// (C) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; }

This is an alternative to addGlob(), addPattern() uses the “standard regular expression” to filter out files. But take note again, this will not drill into the sub-folders.

 

 

6) RECURSIVELY ADD FOLDER AND SUB-FOLDERS

6-recursive.php
<?php 
// (A) NEW ZIP ARCHIVE OBJECT
$zip = new ZipArchive();
$zipfile = "demoD.zip";
$tozip = __DIR__ . "/test/";

// (B) OPEN/CREATE ZIP FILE
if ($zip->open($zipfile, ZipArchive::OVERWRITE | ZipArchive::CREATE) === true) {
  // (B1) RECURSIVE ADD
  function zipall ($folder, $base, $ziparchive) {
    // FOLDER NAME INSIDE ZIP
    $options = ["remove_all_path" => true];
    if ($folder != $base) { 
      $options["add_path"] = substr($folder, strlen($base));
    }

    // ADD CURRENT FOLDER TO ZIP ARCHIVE
    echo $ziparchive->addGlob($folder."*.{jpg,png,gif}", GLOB_BRACE, $options)
     ? "Folder added to zip" : "Error adding folder to zip" ;

    // ADD FOLDERS IN FOLDER
    $folders = glob($folder . "*", GLOB_ONLYDIR);
    if (count($folders)!=0) { foreach ($folders as $f) {
      zipall($f."/", $base, $ziparchive);
    }}
  }
  zipall($tozip, $tozip, $zip);

  // (B2) CLOSE ZIP
  echo $zip->close()
   ? "Zip archive closed" : "Error closing zip archive" ;
}

// (C) FAILED TO OPEN/CREATE ZIP FILE
else { echo "Failed to open/create $zipfile"; } 

Finally, this is sadly the way to zip an entire folder, along with the sub-folders inside… Not going to explain this line-by-line, but essentially, use a recursive function to drill into the sub-folders themselves.

 

EXTRAS

That’s it for all the example code, and here is a summary of all the zip functions.

 

THE ZIP FUNCTIONS AT A GLANCE

Function Description Reference Link
open() Open a zip archive. Click Here
addEmptyDir() Add an empty folder inside the zip archive. Click Here
addFile() Add a file into the zip archive. Click Here
addFromString() Create a file in the zip archive from a string. Click Here
addGlob() Add files into the zip archive that matches a given GLOB pattern. Click Here
addPattern() Add files into the zip archive that matches a given pattern. Click Here
close() Close and save the zip archive. Click Here

 

THE END

Thank you for reading, and we have come to the end of the tutorial. I hope that it has helped you to better understand zip in PHP, and if you have anything to share with this guide, please feel free to comment below. Good luck and happy coding!

3 thoughts on “Add Files & Folders In PHP ZIP (Basics, Entire Folder, Recursive)”

  1. Many thanks for this. It’s been a real lifesaver for our webpages for PHP 7.0.

    I’m having trouble using the recursive script using PHP 8.0.

    Can you confirm whether this version should be compatible please?

Leave a Comment

Your email address will not be published. Required fields are marked *