How to create and download a Zip file with PHP

PHP provides ZipArchive Class which allows us to create a Zip file. This class makes file creation easier.

Programmatically Zip creation mainly requires when preparing the group of files and folders for downloading.

In the demonstration, I am creating a function that will read all files and folders from the specified directory and add them to the ZipArchive class object.

How to create and download a Zip file with PHP


Contents

  1. HTML
  2. PHP
  3. CSS
  4. Demo
  5. Conclusion

1. HTML

Creating a <form> which have two button elements, one for Create Zip and another for Download.

Completed Code

<div class='container'>
 <h2>Create and Download Zip file using PHP</h2>
 <form method='post' action=''>
   <input type='submit' name='create' value='Create Zip' />&nbsp;
   <input type='submit' name='download' value='Download' />
 </form>
</div>

2. PHP

I have created includes folder within the project where I stored some files and folders.

Create Zip

Create ZipArchive Class object for Zip file creation. Define a function createZip() to read files and directory from the specified directory path.

If file

If the reading value is the file then add it to zip object using addFile() method.

If directory

If the value is a directory then create an empty directory and call createZip() function where pass the directory path.

Download Zip

Check if the zip file exists or not. If it exists then download and remove it from the server.

Completed Code

<?php 
// Create ZIP file
if(isset($_POST['create'])){
  $zip = new ZipArchive();
  $filename = "./myzipfile.zip";

  if ($zip->open($filename, ZipArchive::CREATE)!==TRUE) {
    exit("cannot open <$filename>\n");
  }

  $dir = 'includes/';

  // Create zip
  createZip($zip,$dir);

  $zip->close();
}

// Create zip
function createZip($zip,$dir){
  if (is_dir($dir)){

    if ($dh = opendir($dir)){
       while (($file = readdir($dh)) !== false){
 
         // If file
         if (is_file($dir.$file)) {
            if($file != '' && $file != '.' && $file != '..'){
 
               $zip->addFile($dir.$file);
            }
         }else{
            // If directory
            if(is_dir($dir.$file) ){

              if($file != '' && $file != '.' && $file != '..'){

                // Add empty directory
                $zip->addEmptyDir($dir.$file);

                $folder = $dir.$file.'/';
 
                // Read data of the folder
                createZip($zip,$folder);
              }
            }
 
         }
 
       }
       closedir($dh);
     }
  }
}

// Download Created Zip file
if(isset($_POST['download'])){
 
  $filename = "myzipfile.zip";

  if (file_exists($filename)) {
     header('Content-Type: application/zip');
     header('Content-Disposition: attachment; filename="'.basename($filename).'"');
     header('Content-Length: ' . filesize($filename));

     flush();
     readfile($filename);
     // delete file
     unlink($filename);
 
   }
}
?>

3. CSS

.container{
   margin: 0 auto;
   width: 50%;
   text-align: center;
}

input[type=submit]{
   border: 0px;
   padding: 7px 15px;
   font-size: 16px;
   background-color: #00a1a1;
   color: white;
   font-weight: bold;
}

4. Demo

View Demo


5. Conclusion

The above-defined function createZip() accepts the path of the directory as a parameter. It will read all files and folders from the path and add them to the zip file.

You can also use ZipArchive Class to unzip the Zip file.

If you found this tutorial helpful then don't forget to share.
Are you want to get implementation help, or modify or extend the functionality of this script? Submit paid service request.

26 thoughts on “How to create and download a Zip file with PHP”

  1. I have this issue :
    ZipArchive::close(): Failure to create temporary file: Permission denied in…
    you know what could I do? I’m working on localhost

    Reply
  2. Very helpful article.
    But I had some question. How can I implement this code in static website? That website only have html, css and js code , how to do a creating zip file functionality.

    Thanks Advance for reply.

    Reply
  3. Hi, Excellent Tutorial. How do I implement this inside a wordpress website. My wordpress website has foldername as of the post name, which I can pass through as using function get_the_title(), the folder contains mp3 files, and the files will be zipped and sent to the user.
    I like to provide a button that is available on every post., that can be clicked like in the demo, But instead of two buttons, a single one, to create and download the zip file.
    Suggestion:
    You could even do this as a wordpress plugin, It will be a great hit and useful to many., A premium version with analytics tracking code inbuilt.
    To include in every post, you can make the button be inserted to the single.php, etc.

    Reply
    • Hi Senthil,
      You can create Zip in WordPress using the same code in the tutorial you just need to update the directory path. For handling it with a single button you need to move the create and download code in button submit. Thanks for the suggestion I will try to publish zip creation in WordPress tutorial soon.

      Reply
    • Hi Senthil,
      You can do this by creating a separate PHP file for download –

      $filename = $_GET["filename"]; 
      ob_end_clean();
      header("Content-Type: application/octet-stream; "); 
      header("Content-Transfer-Encoding: binary"); 
      header("Content-Length: ". filesize($filename).";"); 
      header("Content-disposition: attachment; filename=" . $filename);
      readfile($filename);
      die();

      Pass filename parameter using URL like – download.php?filename=index.php

      Reply
  4. Hi, How to add files from a specific directory to zip,?. Suppose the code is example.com/demo/codes/index.php.
    I need to add the files inside a example.com/demo/files/folder1/.
    How do I achieve this?

    Reply
  5. Hi there!

    Thank you so much for putting this together, this has helped me me so much 🙂

    I do have an issue though. In the demo, if you change $dir to ‘includes/folder/’ the resulting zip file still has the full file path and puts ‘folder’ inside the ‘includes’ folder.

    How would I get the zip to start at ‘folder’?

    I was looking here – https://www.php.net/manual/en/class.ziparchive.php at the user contributed notes and it appears you need to create a new variable and use dirname() or basename() to give addfile() a second parameter, but I have tried both and resulting zip file structure is all messed up.

    Any ideas?

    Reply
      • I’ll add my contribution since this was an excellent post (props to Yogesh) and I figured this piece out.

        All you have to do is change this line
        $zip->addFile($dir.$file);
        to this
        $zip->addFile($dir.$file,$file);

        And the program will do what you want.

  6. When I download the zip if it contains more than 200 files I am getting null file download
    could you please help me to sort it out?

    Reply

Leave a Comment