Ramui webblog Free Blog Script

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:
Reazool on Dec 18, 06:58 said:

Why variable pass by reference

Why variable $zip pass by reference in function recurse_zip? Is it mandatory?
admin on Dec 18, 07:03 said:

Pointer variables always pass by reference

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.
sheetal on Jul 06, 06:30 said:

How to store zipped directory in another folder

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
admin on Jul 07, 13:18 said:

Re: How to store zipped directory in another folder

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
JStern on Jul 07, 17:24 said:

Undefined var

your line $f=explode('/',$filename); breaks.
$filename is not declared yet.
admin on Jul 07, 18:19 said:

Re: Undefined var

Thank you for mentioning this error. I already rectify it.
Thank you very much.
falkon303 on Nov 26, 22:30 said:

error in posting

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>
papy98 on Jan 05, 14:27 said:

error

Parse error: syntax error, unexpected '}'
Edward on Jan 12, 19:19 said:

No title

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.
admin on Jan 14, 04:35 said:

Thanks to Edward

Thank you very much.
camilner on Jun 28, 13:00 said:

Specify directory for recursive zip

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
emprear on Jun 28, 15:54 said:

fix php warning

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
admin on Jun 28, 19:10 said:

How to input source and destination folder for recursive Zip

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.
Rizwan on Aug 23, 03:54 said:

Corrupted Zip

My zip is creating successfully. but when i m extracting that zip, it shows the error that "Zip file is corrupted". any suggession ?
admin on Aug 24, 03:54 said:

Re: Corrupted Zip

I have tested it on localhost. Do you tell me where you tested it?
Rizwan on Aug 24, 09:15 said:

Corrupted Zip

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.
admin on Aug 25, 08:05 said:

Sorry

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.
Rizwan on Aug 26, 05:16 said:

Sitll working

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".
naomihoney on Aug 27, 19:59 said:

Error

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
Rizwan on Aug 29, 04:27 said:

Re: Error

hello naomihoney. Go to php.ini file and uncomment the extension=php_zip.dll
admin on Aug 29, 08:11 said:

Thank you

Thank you very much. This is very useful information for me.
morteza on Jan 16, 19:24 said:

how to zip array files

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'
);
admin on Jan 20, 14:33 said:

How to zip array of files

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;
Vijay on Feb 10, 12:35 said:

Force file download after successfull Zip creation

Hello Ramui,
Great script.It worked fine for me. I want to now download the file as soon as the zip file is created. Means forcefully ask for downloading the file soon after zip creation. I have written a script which asks for downlaod. But when I save the file and try to extract it, it says the file is corrupted. :( Any help is really appreciated. Thanks in Advance.
webideias on Feb 27, 17:43 said:

Blank Directories

Hello Ramui
I would like to ask you, if there is a possibility to force empty directories to the archive? I'm using this for backing up folders that may be empty.

Thank you for your help.
Best regards
Pedro
admin on Feb 28, 02:23 said:

Inserting empty directory in ZIP archive

I think you can do it as a normal directory.
Please download and try it on your local computer.
webideias on Feb 28, 09:43 said:

Empty dirs

Hello Ramui
I've downloaded the generated zip and it does not have the empty folder.

Best regards.
Pedro
harimaliya on Apr 19, 10:49 said:

how to exclude multiple directory and file in recurseZip function

Code
class recurseZip
{



private function recurse_zip($src,&$zip,$path) 
{

$cars=array("preload-images","mybackp","phpFileTree");
        $dir = opendir($src);
	
        while(false !== ( $file = readdir($dir)) ) 
		{	
			
			
			if (( $file != '.' ) && ( $file != '..' ))
			 {
							 
                if ( is_dir($src . '/' . $file) ) 
				{
                
				    $this->recurse_zip($src . '/' . $file,$zip,$path);
					
                }
                else
				 {		
						$find = "mybackp";
						if(strpos($src, $find) ===false)
						{
					
						$zip->addFile($src . '/' . $file,substr($src . '/' . $file,$path));
						
						}
					
					}
				
				
             }
			 
        }
        closedir($dir);
		
		
		
}

public function compress($src,$dst)
{
		
		if(substr($src,-1)==='/'){$src=substr($src,0,-1);}
		if(substr($dst,-1)==='/'){$dst=substr($dst,0,-1);}
		
        $path=strlen(dirname($src).'/');
		//print_r($path);
        $filename=substr($src,strrpos($src,'/')+1).date('d-F-Y').'_at_'.date('H-i-sA').'.zip';
		$dst=empty($dst)? $filename : $dst.'/'.$filename;
		
		@unlink($dst);
        $zip = new ZipArchive;
        $res = $zip->open($dst, ZipArchive::CREATE);
		
        if($res !== TRUE)
		{
                echo 'Error: Unable to create zip file';
                exit;
		}
        if(is_file($src))
		{ // print_r($src);
		
		 $zip->addFile($src,substr($src,$path));
		 print_r($src);
		}
        else
		{
                if(!is_dir($src))
				{
                     $zip->close();
					// echo $dst;
                     @unlink($dst);
                     echo 'Error: File not found';
                     exit;
				}
        $this->recurse_zip($src,$zip,$path);
		//print_r($src);
		}
        $zip->close();
        return $dst;
}
}


$backupfile = "c:\wamp\www\backup_zip";
$destination = dirname(__FILE__)."/mybackp/".'MyBlogBackup'.date('d-F-Y').'_at_'.date('H-i-sA').'.zip';

$src="c:/wamp/www/backup_zip";
//$src='source/images';
//Destination folder where we create Zip file.
$dst='mybackp';
$z=new recurseZip();
echo $z->compress($src,$dst);

//////////////////////////////////////////////////
this is my code

i want to exclude multiple directory and file
reply me
robmarston on Dec 29, 04:09 said:

Prematurely closing directories causing error

If you're seeing "Warning: readdir(): 2 is not a valid Directory resource..." simply move "closedir($dir);" outside the while loop. Hope this helps!

Add comment