How to Zip Files or Folder On The Fly Using PHP

Sometimes in web programming when dealing with multiple files or directory download operations, it is better to serve the user with a single zip file rather than let the user manually download the file one by one using direct link download . To overcome this problem, we have to create a zip file on the fly without have to manually create it using any commpresion tools or softwares.

PHP has some functions dealing with file compression that enables us to create zip file on the fly. In this tutorial i will use PHP CreateZipFile classs package from Rochak Chauhan. I have made some examples below to explain how to craete zip file on the fly from multiple files or directory.

Example 1, create zip file from existing files:

<?php
include_once 'CreateZipFile.inc.php';

$createZip = new CreateZipFile;

$createZip->addDirectory('/');

$filecontent1 = file_get_contents('fileone.txt');
$filecontent2 = file_get_contents('filetwo.txt');

$createZip->addFile($filecontent1, '/fileone.txt');
$createZip->addFile($filecontent2, '/filetwo.txt');

$zipFileName = 'myzip.zip';
$handle       = fopen($zipFileName, 'wb');
$out           = fwrite($handle, $createZip->getZippedFile());

fclose($handle);

$createZip->forceDownload($zipFileName);

@unlink($zipFileName);
?>

To create zip file:

  • add a directory into zip file using addDirectory method
  • add files into directory using addFile method
  • create zip file temporary for download and delete it after the file is downloaded

Example 2, create zip file for a directory with it’s contents/subdirectories

<?php
include_once 'CreateZipFile.inc.php';

$createZip = new CreateZipFile;

$createZip->zipDirectory('/testdir', '');

$zipFileName = 'myzip.zip';
$handle       = fopen($zipFileName, 'wb');
$out           = fwrite($handle, $createZip->getZippedFile());

fclose($handle);

$createZip->forceDownload($zipFileName);

@unlink($zipFileName);
?>

To create zip file for a directory, use zipDirectory method that takes two arguments, first is the name of directory that want to be zipped and second is directory name for zipped file.

facebooktwittergoogle_plusredditpinterestlinkedinmailby feather

Comments

  1. rbueno says

    Hi, I want to make comment about this.

    In your variable $out, you forgot to close your fwrite function.

    Its:

    $out = fwrite($handle, $createZip->getZippedFile());

    Thanks

  2. says

    This works well (with CreateZipFile.inc.php of course)… but when zipping a whole directory (folder) it copies the entire folder tree.

    How do I make it only put the specified files from a folder in the zip container without the folder tree?

    ie.
    I have a folder on my main directory named `myfolder`… it contains 3 text files (a.txt, b.txt, c.txt)…
    If I use your example it will put it in the zip archive like this…
    myfolder / a.txt
    myfolder / b.txt
    myfolder / c.txt

    I don`t want the `myfolder`to be put in the zip… I would like it to just put the txt files in there..

    Please show me the exact edit to perform in the CreateZipFile.inc.php file to enable the output as I have requested.

    I have been trying to edit it without any success.

    Thank you.

    • says

      hello underdog..

      you can use my edited CreateZipFile.inc.php (http://londatiga.net/downloads/CreateZipFile.inc.zip)

      and use following code:

      < ?php include_once 'CreateZipFile.inc.php'; $createZip = new CreateZipFile; $createZip->zipMyDirectory(‘underdog’);

      $zipFileName = ‘myzip4.zip’;
      $handle = fopen($zipFileName, ‘wb’);
      $out = fwrite($handle, $createZip->getZippedFile());

      fclose($handle);

      $createZip->forceDownload($zipFileName);

      @unlink($zipFileName);
      ?>

      Hope it will resolve your problems

      Regards

      • TY says

        Thanks for your site that I have been finding to get zip file without path.

        I have found that your mod doesn’t include subfolder and its content.

        I am want to make a zip file with following structure.

        /var/www/Folder_A/Folder_B
        Foler_B
        |- a.file
        |- b.file

        Or is there any way create Folder_B and put files under the new folder??

  3. Nirvikar says

    Hi,
    I want to ask how can i use you code
    in php4
    please tell me its urgent

    Thanks
    Nirvikar Satsangi

    • says

      Hi,

      To use the code in PHP4, modify CreateZipFile.inc.zip:

      Remove ‘public’ and ‘private’ keyword at method declaration and replace ‘public’ keyword with ‘var’ at member variable declaration.

  4. Nirvikar says

    I modify you code and know it download blank zip file,in my code this getZippedFile() is working but download
    blank zip file

    Please help its urgent

    Thanks

    • says

      Hi, could you show me your code? I have no problems with php4 modified CreateZipFile.inc.php (public & private keyword removed).

  5. seularts says

    This script is cool, but there is one small issue, it does not include empty folders from the folder tree :( Any suggestions!?

    • says

      //download code from http://ekomkaar.com/script/zipme.txt copyright Manjit Singh Jabbal, Don’t delete this line include top of file.
      function create_zip($files = array(),$destination = ”,$overwrite = false)
      {
      if(file_exists($destination) && !$overwrite)
      {
      return false;
      }
      $valid_files = array();
      if(is_array($files))
      {
      foreach($files as $file)
      {
      if(file_exists($file))
      {
      $valid_files[] = $file;
      }
      }
      }
      if(count($valid_files))
      {
      $zip = new ZipArchive();
      if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
      {
      return false;
      }
      foreach($valid_files as $file)
      {
      $zip->addFile($file,$file);
      }
      $zip->close();
      return file_exists($destination);
      }
      else
      {
      return false;
      }
      }

      $files_to_zip = array(
      ‘file1′,’file2′,’file n’
      );
      $result = create_zip($files_to_zip,’my-archive.zip’);
      header(“Content-Type: archive/zip”);
      header(“Content-Disposition: attachment; filename=my-archive”.”.zip”);
      $filesize = filesize(‘my-archive.zip’);
      header(“Content-Length: $filesize”);
      $fp = fopen(“my-archive.zip”,”r”);
      echo fpassthru($fp);
      unlink(“my-archive.zip”);
      //visit http://sadamusic.com for music and movies.

  6. says

    open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
    {
    return false;
    }

    //Iterate all Files and include them
    foreach($valid_files as $file)
    {
    $zip->addFile($file,$file);
    }
    $zip->close();
    //Return the File
    return file_exists($destination);
    }
    else
    {
    return false;
    }
    }

    //You can create any function which include all files from folder or whatever you like its your choice. I use it on http://sadamusic.com to zip songs and movie files. and zip whole directory at once.
    $files_to_zip = array(
    ‘File1′,’File2′,…,’File n’
    );

    //Call function with files and Name of Zip Class you can use tempnam to generate unique name, header for download to tell size of download.
    $result = create_zip($files_to_zip,’my-archive.zip’);
    header(“Content-Type: archive/zip”);
    header(“Content-Disposition: attachment; filename=my-archive”.”.zip”);
    $filesize = filesize(‘my-archive.zip’);
    header(“Content-Length: $filesize”);
    //Read the File and put into output buffer for user
    $fp = fopen(“my-archive.zip”,”r”);
    echo fpassthru($fp);
    //Delete the File.
    @unlink(“my-archive.zip”);
    ?>

    Contact me if you need more update directly mail me at info@ekomkaar.com and don’t forget to visit http://sadamusic.com to download free music and promote if you like it.

  7. says

    I guess above code miss here is full code or you can doenload code from http://ekomkaar.com/source/zipme.txt

    open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
    {
    return false;
    }

    //Iterate all Files and include them
    foreach($valid_files as $file)
    {
    $zip->addFile($file,$file);
    }
    $zip->close();
    //Return the File
    return file_exists($destination);
    }
    else
    {
    return false;
    }
    }

    //You can create any function which include all files from folder or whatever you like its your choice. I use it on http://sadamusic.com to zip songs and movie files. and zip whole directory at once.
    $files_to_zip = array(
    ‘File1′,’File2′,…,’File n’
    );

    //Call function with files and Name of Zip Class you can use tempnam to generate unique name, header for download to tell size of download.
    $result = create_zip($files_to_zip,’my-archive.zip’);
    header(“Content-Type: archive/zip”);
    header(“Content-Disposition: attachment; filename=my-archive”.”.zip”);
    $filesize = filesize(‘my-archive.zip’);
    header(“Content-Length: $filesize”);
    //Read the File and put into output buffer for user
    $fp = fopen(“my-archive.zip”,”r”);
    echo fpassthru($fp);
    //Delete the File.
    @unlink(“my-archive.zip”);
    ?>

  8. says

    function create_zip($files = array(),$destination = ”,$overwrite = false)
    {
    if(file_exists($destination) && !$overwrite)
    {
    //If File Already Exist or Write Permission Denied
    return false;
    }

    //Array for include all valid link files.
    $valid_files = array();
    if(is_array($files))
    {
    foreach($files as $file)
    {
    if(file_exists($file))
    {
    $valid_files[] = $file;
    }
    }
    }

    //If Valid Link more than 0
    if(count($valid_files))
    {
    //Reference to Zip class
    $zip = new ZipArchive();
    if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
    {
    return false;
    }

    //Iterate all Files and include them
    foreach($valid_files as $file)
    {
    $zip->addFile($file,$file);
    }
    $zip->close();
    //Return the File
    return file_exists($destination);
    }
    else
    {
    return false;
    }
    }

    //You can create any function which include all files from folder or whatever you like its your choice. I use it on http://sadamusic.com to zip songs and movie files. and zip whole directory at once.
    $files_to_zip = array(
    ‘File1′,’File2′,…,’File n’
    );

    //Call function with files and Name of Zip Class you can use tempnam to generate unique name, header for download to tell size of download.
    $result = create_zip($files_to_zip,’my-archive.zip’);
    header(“Content-Type: archive/zip”);
    header(“Content-Disposition: attachment; filename=my-archive”.”.zip”);
    $filesize = filesize(‘my-archive.zip’);
    header(“Content-Length: $filesize”);
    //Read the File and put into output buffer for user
    $fp = fopen(“my-archive.zip”,”r”);
    echo fpassthru($fp);
    //Delete the File.
    @unlink(“my-archive.zip”);

  9. says

    here is full code for it visit http://sadamusic.com for new music and movie

    //download code from http://ekomkaar.com/script/zipme.txt copyright Manjit Singh Jabbal, Don’t delete this line include top of file.
    function create_zip($files = array(),$destination = ”,$overwrite = false)
    {
    if(file_exists($destination) && !$overwrite)
    {
    return false;
    }
    $valid_files = array();
    if(is_array($files))
    {
    foreach($files as $file)
    {
    if(file_exists($file))
    {
    $valid_files[] = $file;
    }
    }
    }
    if(count($valid_files))
    {
    $zip = new ZipArchive();
    if($zip->open($destination,$overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true)
    {
    return false;
    }
    foreach($valid_files as $file)
    {
    $zip->addFile($file,$file);
    }
    $zip->close();
    return file_exists($destination);
    }
    else
    {
    return false;
    }
    }

    $files_to_zip = array(
    ‘file1′,’file2′,’file n’
    );
    $result = create_zip($files_to_zip,’my-archive.zip’);
    header(“Content-Type: archive/zip”);
    header(“Content-Disposition: attachment; filename=my-archive”.”.zip”);
    $filesize = filesize(‘my-archive.zip’);
    header(“Content-Length: $filesize”);
    $fp = fopen(“my-archive.zip”,”r”);
    echo fpassthru($fp);
    unlink(“my-archive.zip”);

  10. Sherman says

    Hello,
    I have no permission to write file on server. Then in this case how can i create a zip file for multiple text files.

    Please reply

  11. Sherman says

    Hello,
    I have no permission to write file on server. Then in this case how can i create a zip file for multiple text files. i want to download the zip file only. I dont want to store it on server. Because I have no permission.

    Please reply fast.

  12. Mashi says

    I want to convert this text file in to a zip file when it is downloaded and the text file should be deleted.

    <?php
    $msg="";
    $filename = "";
    $content = "";
    if(isset($_POST["submit"])){
    $filename = $_POST["filename"];
    $content = $_POST["content"];
    $over=false;
    if(isset($_POST["overwrite"])){
    $over=true;
    }
    if($filename!=""){
    $pos = strpos($filename, ".");
    if($posopen($zipfilename, ZIPARCHIVE::CREATE)!==TRUE)
    {
    $filecontent = file_get_contents(‘$filename.txt’);

    $createZip=”";

    $createZip->addFile($filecontent, ‘/$filename.txt’);
    }
    fclose($filehand);
    $zip->close();
    $msg=”Download $zip (to download- right click on the link and select save target as/ save link as)” ;
    }else{
    $msg=”File already exist”;
    }
    }else{
    $msg=”Please enter file name”;
    }
    unset($_POST["submit"]);

    }

    ?>

    td{
    vertical-align:middle;
    }

    File Name

     
    overwrite existing

    Content

     

  13. Yvonne says

    Hi!

    Thanks for this tutorial!

    I removed the “exit;” in the forceDownload function because “unlink” didn’t work.

    My download button works fine now for a small number of photos, but I have difficulties with larger zip archives. The apache log says:

    “PHP Fatal error: Allowed memory size of 134217728 bytes exhausted (tried to allocate 57020455 bytes) in /srv/www/photos/CreateZipFile.inc.php on line 192″

    It seems that the allowed memory size is bigger than the memory the skript tries to allocate? So why is there an error?

    line 192 is this one:
    $newOffset = strlen(implode(“”, $this->compressedData));

    Is there any possibility to fix that problem?

    Thanks!

    Yvonne

  14. says

    $createZip->zipMyDirectory(’underdog’);

    Try It.
    $current_directory = getcwd();
    $final_directory =
    $current_directory.”/files/user_files”;
    $createZip->zipMyDirectory(”.$final_directory.”);

  15. swetha says

    Hi I am not able to zip many files. I need to zip 100 image files from the IIS7 server and the server is throwing a 500 internal server error. Any idea on what to do?

    Thanks

  16. says

    Hi Lorenz,

    Everything is fine in this script. But when I am using it for dynamic list of files in foreach loop for an array, it is generating a corrupted zipped file. Do u have any solution for the same.
    addDirectory(‘/’);

    $dir = scandir(‘../filestore/vrs_files’);

    $scanned_directory = array_diff(scandir(‘../filestore/vrs_files’), array(‘..’, ‘.’));

    $i=0;
    foreach($scanned_directory as $files){

    $path = $_SERVER['DOCUMENT_ROOT'].”filestore/vrs_files/”.$files;
    $filecontent = file_get_contents($path);

    $createZip->addFile($filecontent, $files);
    $i++;
    }
    $zipFileName = ‘myzip.zip’;
    $handle = fopen($zipFileName, ‘wb’);

    $out = fwrite($handle, $createZip->getZippedFile());fclose($handle);

    $createZip->forceDownload($zipFileName);

    @unlink($zipFileName);

    ?>

  17. maxxin says

    if i have files wich will together be over 20mb it will always write max 20mb on disc?! what can be the problem… ?!

    even the files in the zip will be cuttet to 7.670.724 bytes, that seems to be a max. size. how can i bring it up?

    thanks for help!
    /tm

  18. claudio says

    Hi,
    I’m trying to put a progress bar whyle executing your script but if i write a or any echo, the resulting zip results corrupted. the echo or div or any html part its inserted in the final zip.
    Can I print something during zip operation?

    regards
    thanks
    Claudio

Leave a Reply

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