If you want to use ZipArchive to archive a folder, you will notice that there is no dedicated method to do this. You will need to make a recursive function to do this.
function addDirectoryToZip(&$zip, $dir) { foreach(glob($dir . '/*') as $file) { if(is_dir($file)) addDirectoryToZip($zip, $file); else $zip->addFile($file); } }
Now you have the function, but if you want to add to archive a directory path, something like '/path/to/my/directory', you will find that path in the archive too. So, to have a nice archive, only with tha one directory you need to archive, we will rewrite the function:
function addDirectoryToZip(&$zip, $dir, $base = 0) { foreach(glob($dir . '/*') as $file) { if(is_dir($file)) addDirectoryToZip($zip, $file, $base); else $zip->addFile($file, substr($file, $base)); } }
Now, the function substracts the base directory from the local name of the file, the name in the zip archive.
Assuming that you have a folder '/path/to/my/folder', you will call the function like this:
$zip = new ZipArchive; $zip->open('ziparchive.zip', ZipArchive::CREATE); addDirectoryToZip( $zip, // the ZipArchive object sent by refference '/path/to/my/folder', // The path to the folder you wish to archive strlen('/path/to/my/folder') + 1 // The string length of the base folder );
To make this even easier, you can extend the ZipArchive class and insert the function into the class:
class MyZipArchive extends ZipArchive{ public function addDirectory($dir, $base = 0) { foreach(glob($dir . '/*') as $file) { if(is_dir($file)) $this->addDirectory($file, $base); else $this->addFile($file, substr($file, $base)); } } } // class usage $zip = new ZipArchive; $zip->open('ziparchive.zip', ZipArchive::CREATE); $zip->addDirectory( '/path/to/my/folder', // The path to the folder you wish to archive strlen('/path/to/my/folder') + 1 // The string length of the base folder );
Have fun!
// class usage
ReplyDelete$zip = new MyZipArchive;
#fixed ;)
Easy, simple, efficient ! Fucking great then !
ReplyDeleteTHank you very very much..I've spend 2 hours on ziparchive::addglob !
ReplyDeleteThis doesn't seem quite right It adds the files from the directory, but it doesn't create the actual directory first. Drop the second argument on the $zip->addFile($file, substr($file, $base)); to just be $zip->addFile($file); and now you are good to go. Then you can add multiple directories and keep the file structure
ReplyDelete