PHP Zip files and directory

Sometimes you require zipping a file or even an entire directory at your server with PHP. The best way is to use ZipArchive class to do it. If you have PHP 5.2 or later version installed on your server and if zip library is enabled then ZipArchive class will be available to you. This class has lots of useful member function which makes easier in zipping files.

How to use ZipArchive class in PHP

Like any other classes first you have to create an object of ZipArchive class to use its public member functions.
$zip-> new ZipArchive();

PHP create zip file

After creating an object of ZipArchive class now you can create a new zip file. The member function open() is used to create a new zip file or to open an existing zip archive.

Code | Download
$filename='backup.zip';
if(($zip->open($filename, ZipArchive::CREATE))!==true){ die('Error: Unable to create zip file');}

Please remember if the file 'backup.zip' already exists this function will open the existing file.

Adding files inside a zip archive

To add a new file inside a zip archive use member function
addFile('realname',['saveAs']).
As you can see this function takes two arguments, one is the 'realname', i.e. name of the file to be added and other is the optional argument 'saveAs'. The 'saveAs' parameter is the name of the file by which you want to add it inside the zip archive. If you omit this parameter the file will be saved by its real name. The importance of this parameter can be explained by the following example.

Code | Download
<?php
//File to be added inside zip archive.
$file='/home/domain/public_html/example.txt';
//Open zip archive.
$zip-> new ZipArchive();
if(($zip->open('test.zip', ZipArchive::CREATE))!==true){ die('Error: Unable to create zip file');}
//Add file by its real name.
$zip->addFile($file);
//Add the same file with different name say, 'newname.txt'.
$zip->addFile($file,'newname.txt');
//Close zip archive.
$zip->close();
//Download zip file.
header("Location: test.zip");
exit;
?>

After running this script you will be prompted to download test.zip file. Save this file at your computer desktop and open it. You will see the file 'newname.txt' is at the root of your zip archive while the file 'example.txt' resides inside directories '/home/domain/public_html/'.

Closing an open zip archive

In the above example I use a new member function close(). This function is used to close an open zip archive. Although PHP will automatically close it at the end of the script but you should do it yourself.

Zip a directory in PHP

You can insert a complete directory, all files and subdirectory in it into a zip archive by PHP. The most efficient way is to use a recursive program to do it. Below, I write a recursive function which can zip a directory.

Code | Download
function recurse_zip($src,&$zip,$path_length) {
        $dir = opendir($src);
        while(false !== ( $file = readdir($dir)) ) {
            if (( $file != '.' ) && ( $file != '..' )) {
                if ( is_dir($src . '/' . $file) ) {
                    recurse_zip($src . '/' . $file,$zip,$path_length);
                }
                else {
                    $zip->addFile($src . '/' . $file,substr($src . '/' . $file,$path_length));
                }
            }
        }
        closedir($dir);
}
//Call this function with argument = absolute path of file or directory name.
function compress($src)
{
        if(substr($src,-1)==='/'){$src=substr($src,0,-1);}
        $arr_src=explode('/',$src);
        $filename=end($src);
        unset($arr_src[count($arr_src)-1]);
        $path_length=strlen(implode('/',$arr_src).'/');
        $f=explode('.',$filename);
        $filename=$f[0];
        $filename=(($filename=='')? 'backup.zip' : $filename.'.zip');}
        $zip = new ZipArchive;
        $res = $zip->open($filename, ZipArchive::CREATE);
        if($res !== TRUE){
                echo 'Error: Unable to create zip file';
                exit;}
        if(is_file($src)){$zip->addFile($src,substr($src,$path_length));}
        else{
                if(!is_dir($src)){
                     $zip->close();
                     @unlink($filename);
                     echo 'Error: File not found';
                     exit;}
        recurse_zip($src,$zip,$path_length);}
        $zip->close();
        header("Location: $filename");
        exit;
}

PHP Zip class to compress a file or directory

For the convenience of the user here I create a PHP class file 'recurseZip.php'. You can use this class to compress a single file or entire directory.

How to Use: To use this class in your project,

  1. You have to include this file in your project.
  2. Create class object.
  3. Call the public function compress(); this function takes two arguments, source and destination. You can omit the second argument, and then working folder will be the destination. On success this function will return the Zip file name.

System Requirements: The system required to install or run this script is,

  • PHP version 5.2.1 or higher;
  • PHP extension Zlib (http://www.zlib.net/) written by Jean-loup Gailly;

Download PHP Zip directory class

Comments:

Why variable pass by reference

COMMENT BY: Reazool DATE: Dec 18, 06:58
Why variable $zip pass by reference in function recurse_zip? Is it mandatory?

Pointer variables always pass by reference

COMMENT BY: admin DATE: Dec 18, 07:03
A function can accept arguments in two ways; either by value or by reference. When you pass argument by value a copy of original data is sent to the function. During processing function can alter that data, but the original data remains unchanged. On the other hand when you pass data by reference (by using '&' before the argument of the function statement) the memory address of the original data is sent to the function. Here during function works on original data. In recurse_zip() function we need to handle the original zip file open by ZipArchive class object $zip. So here I pass the $zip pointer by reference. In short you should remember that all pointer data (like $handle from fopen function) always pass through reference.

How to store zipped directory in another folder

COMMENT BY: sheetal DATE: Jul 06, 06:30
Hello,

I have used script for creating zip directory.

Nice script.

However ,I want to store zipped directory in another folder.Now, its saving zipped directory in same folder.

What changes have to do in the script so that zipped directory will store in another directory?

Ur help is required.

Thanks,

Sheetal

Re: How to store zipped directory in another folder

COMMENT BY: admin DATE: Jul 07, 13:18
Hello,
Thank you for your interest. If you want to store in different directory then you have to modify the variable $filename. In function compress() see the lines,
$filename=(($filename=='')? 'backup.zip' : $filename.'.zip');}
$zip = new ZipArchive;
Replace them,
Code
$filename=(($filename=='')? 'backup.zip' : $filename.'.zip');}
$yourpath='newfolder/';//or $yourpath='../newfolder/';
$filename=$yourpath.$filename;
$zip = new ZipArchive;
------------------
**Please give me feedback

Undefined var

COMMENT BY: JStern DATE: Jul 07, 17:24
your line $f=explode('/',$filename); breaks.
$filename is not declared yet.

Re: Undefined var

COMMENT BY: admin DATE: Jul 07, 18:19
Thank you for mentioning this error. I already rectify it.
Thank you very much.

error in posting

COMMENT BY: falkon303 DATE: Nov 26, 22:30
my bad, the code for zipping a directory should be -
Code
<?PHP
  $dir = "directory_name";
  $zip = "directory.zip";
  `zip -r $zip $dir`;
?>


from - <a href="http://www.trash.net/~ck/ontheflyzip/" target="_blank">http://www.trash.net/~ck/ontheflyzip/</a>

error

COMMENT BY: papy98 DATE: Jan 05, 14:27
Parse error: syntax error, unexpected '}'

No title

COMMENT BY: Edward DATE: Jan 12, 19:19
THank you!

I could be wrong but..

had to change the line:

Code
  $arr_src=explode('/',$src);
        $filename=end($src);

to
Code
        $arr_src=explode('/',$src);
        $filename=end($arr_src);


also had to remove the '}' at the end of
Code
$filename=(($filename=='')? 'backup.zip' : $filename.'.zip');}
 
to avoid the error above.

Thanks to Edward

COMMENT BY: admin DATE: Jan 14, 04:35
Thank you very much.

Specify directory for recursive zip

COMMENT BY: camilner DATE: Jun 28, 13:00
Hi. I am using the recursive script and want to specify a directory to get the files from. The php script will be in the root web directory of /home/website/main/ but i want to zip the files /home/website/main/images/user/user_id/ . Where do i specify the path?

I'm quite new to using complex php functions. Thank you very much. Chris

fix php warning

COMMENT BY: emprear DATE: Jun 28, 15:54
First sorry by me english
When running original script fist time i get
Parse error: syntax error, unexpected '}' in I:\servidor\test\zipeardir.php on line ...,
Then fix removing } at the end of this line,
Runnig script again work fine, but with php warning
Warning: end() expects parameter 1 to be array, string given in I:\servidor\test\zipeardir.php on line 27
However, the script work fine and backup.zip is created.
Re-reading your post and the comments, i see
COMMENT BY: Edward DATE: Jan 12, 19:19
$arr_src=explode('/',$src);
$filename=end($arr_src);

but apply this fix, the script dont work, none zip is created.

For the moment, i put
$filename=@end($src);
to prevent warning

what is the real solution?
Thanks ramui, the script is great

How to input source and destination folder for recursive Zip

COMMENT BY: admin DATE: Jun 28, 19:10
For the convenience of the user here I create a PHP class file 'recurseZip.php'. You can download use this class to compress a single file or entire directory.
Please try this example code.

Corrupted Zip

COMMENT BY: Rizwan DATE: Aug 23, 03:54
My zip is creating successfully. but when i m extracting that zip, it shows the error that "Zip file is corrupted". any suggession ?

Re: Corrupted Zip

COMMENT BY: admin DATE: Aug 24, 03:54
I have tested it on localhost. Do you tell me where you tested it?

Corrupted Zip

COMMENT BY: Rizwan DATE: Aug 24, 09:15
I am also testing on localhost. The created zip file is also showing 186 kb size,which is correct. but when i am extracting, it shows the "Zip file corrupted" message ?

Thanks for your reply and help.

Sorry

COMMENT BY: admin DATE: Aug 25, 08:05
Hello,
I've tried repeatedly, but can't find any problem in zipping file or directory.
If you solve the problem please post it here.

Sitll working

COMMENT BY: Rizwan DATE: Aug 26, 05:16
I can't find any solution yet. my directory is also zipping successfully. but when i m extracting the directory then it shows error "The archive is corrupted".

Error

COMMENT BY: naomihoney DATE: Aug 27, 19:59
Hi, i got this error, and in "recurseZip.zip" there is no class "ZipArchive.php".So what can i do know.help please.urgent

Fatal error: Class 'ZipArchive' not found in C:\wamp\www\recurseZip\recurseZip.php on line 32

Re: Error

COMMENT BY: Rizwan DATE: Aug 29, 04:27
hello naomihoney. Go to php.ini file and uncomment the extension=php_zip.dll

Thank you

COMMENT BY: admin DATE: Aug 29, 08:11
Thank you very much. This is very useful information for me.

how to zip array files

COMMENT BY: morteza DATE: Jan 16, 19:24
hello,
how to zip array files
Code
$files_to_zip = array(
  'preload-images/1.jpg',
  'preload-images/2.jpg',
  'preload-images/5.jpg',
  'kwicks/ringo.gif',
  'rod.jpg',
  'reddit.gif'
);

How to zip array of files

COMMENT BY: admin DATE: Jan 20, 14:33
To create zip of array of files do the following steps.
  1. Create a zip archive object;
  2. Open a new zip file;
  3. Use foreach loop to add files into the zip file;
  4. Close zip Archive;

Add comment