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.
Like any other classes first you have to create an object of ZipArchive class to use its public member functions.
$zip-> new ZipArchive();
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.
$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.
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.
<?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/'.
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.
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.
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;
}
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.
$filename=(($filename=='')? 'backup.zip' : $filename.'.zip');} $yourpath='newfolder/';//or $yourpath='../newfolder/'; $filename=$yourpath.$filename; $zip = new ZipArchive;------------------