Tutorial: Create a zip file from folders on the fly

For a future project I needed these days some easy to use zip or gzip class to create a zip file from files / folders inside a specified directory. A short search on Google has lead me to the Create ZIP File PHP class from Rochak Chauhan. I tested two other scripts before and must say that this script works great for single files if you add them manually.

To compress a whole directory with an unknown number of files into one zip file I created some class extension to get this job done.

Smarter Web Hosting
Hosting for developers - Free Trial!

Extend the PHP class script

I used some directory functions (opendir, readdir) to get all the files from the specified directory. Inside each directory there are files and “real directories” and directory locations. We need only the real directories. We test each value with “is_file”, “is_dir” and we filter off the directory directions (“.” and “..”). After the “file” is identified, the files content is added to the “addFile” object and for other directories the method “get_file_from_folder” is called again.

class createDirZip extends createZip {
 
	function get_files_from_folder($directory, $put_into) {
		if ($handle = opendir($directory)) {
			while (false !== ($file = readdir($handle))) {
				if (is_file($directory.$file)) {
					$fileContents = file_get_contents($directory.$file);
					$this->addFile($fileContents, $put_into.$file);
				} elseif ($file != '.' and $file != '..' and is_dir($directory.$file)) {
					$this->addDirectory($put_into.$file.'/');
					$this->get_files_from_folder($directory.$file.'/', $put_into.$file.'/');
				}
			}
		}
		closedir($handle);
	}
}

To get the files and sub directories from some directory we use this code:

$createZip = new createDirZip;
$createZip->addDirectory('themes/');
$createZip->get_files_from_folder('blog/wp-content/themes/', 'themes/');

We need create an object from the extension we have just created. Next we need only to define the base directory (which is used in the zip file) and the path to the directory. With this we are able to output the zip file:

$fileName = 'tmp/archive.zip';
$fd = fopen ($fileName, 'wb');
$out = fwrite ($fd, $createZip->getZippedfile());
fclose ($fd);
 
$createZip->forceDownload($fileName);
@unlink($fileName);

Via the method “getZippedfile” all content is added to the file (archive.zip) and the method “forceDownload” will send the created zip file to the browser.

I think this simple function is very helpful if you like to offer the public some dynamic files inside a directory or just to “zip – mail – backup” some directories from your web server using CRON.

Some important update!

After using the same script on two of my websites I got some complains from some (mac) users with the problem that they can’t open the downloaded zip files. While the download via Firefox on Windows and Linux (even most of the time with IE) works fine is this not a the best solution. I checked some other classes but didn’t find a similar solution. My advice is to use the the zip application via the command line:

exec(‘zip -r test.zip your_folder/’);

This is not the same as in this tutorial but will work for most of the machines. Actually is this solution much better even for bigger files…

Comments

  1. http://pecl.php.net

    How simpler can you want than that ? And faster too :O

  2. Hi David,
    sure PECL has a extension that do the same job, but what about the PHP users where the PECL extensions are not available?

    Can you show us a quick example like this one here?

    I checked the test script from the PECL extenstion, is there support for the zip format?

  3. ColdFusion Code:

    <cfzip action=”zip” source=”#ExpandPath(‘./CF8/’)#” file=”#ExpandPath(‘./CF8.zip’)#” overwrite=”true”>

    :)

  4. What about using exec() to create zip files?
    Wouldn’t that be better when handling large files?

  5. Sure using a single Linux command is a good way to do it (just create a gzip file). On a lot of (shared) hosting accounts is this not possible because of missing permissions for Apache.

  6. That’s really cool – didn’t know it could be done !

    Just out of interest – what are you using this script for?

  7. @j7labs,

    I use it for the download of wordpress themes, if several files are updated I don’t need create a zip file over and over again. This way the demo site is using the same files than the files used for the download.

  8. Very nice and useful tutorial, thanks for sharing.

  9. In case of further details or any issue with the class, feel free to contact me.

  10. @Rochak,

    thanks for the offer! (I’m thinking about to release a PHP5 branche)

    Edit: :) the code has already a PHP5 coding style …

  11. I tried using the above technique to produce a zip archive from a directory and it all seems to have worked except the resulting zip archive is invalid. The file that’s created has a size that seems appropriate for the files that have been placed in the zip, but it won’t open. I realize this probably isn’t the best place for support, but I thought I’d leave a note and see if anyone responded. Thanks!

  12. Very nice and useful tutorial, thanks for sharing.

  13. Very nice and useful tutorial, thanks for sharing. I like this and also i give the link of this tutorial on my blog

  14. I have tried out but it does not work.May I am not using it properly.I have many hours in understanding and fixing the problem but it does not work !!

    I have made a simple php file ( 0-make-zip.php) and put up your code in it ) .(edit: removed the link)

    What I want to do is that I want take the manually take the backup of my root folder “public_html” using your script.

    Can some body help ! If it works than it will useful in way that anytime backup of a folder can be taken on the fly.

    [ I do not want to use the CPanel inbuilt option of backup as it takes the backup of all the files and folder and is time intensive ]

  15. Hi Ajay,

    i got this error on the page you have posted here:


    Parse error: syntax error, unexpected '.' in /home/ajayvibh/public_html/0-make-zip.php on line 11

    there are several possibilities that your code is not working maybe your server doesn’t support php5?

  16. Hi Olaf,

    It is on Linux server ( with Cpanel control panel ) with php5 support.

    (edit: don’t provide temp. links)

    Also I am posting at the forum same time.

    Regards,
    Ajay

  17. Hi, I had similar unexpected ‘.’ problem which I solved by changing the quotes in the code as they are not displayed here as single quotes. But I have a similar problem as I want to backup my public_html directory but when I download the zip file it has the directory (in my case backup) but no files inside, any ideas???

    Thanks,
    Sean.

  18. fixed – I needed a forward slash at the end of my directory path *slaps head*

  19. Lol, Sean! I think we’ve all made those silly little mistakes at 1 time or another. Informative article even still. Kudos!

  20. I implemented whole thing as directed and got a zipped file, but when i tried to unzip it an error occured telling that it is corrupt.
    i am working on windows platform and using php5

  21. Hi Vishal,

    never tried the class on windows and it looks like that the class doesn’t create a valid zip file for Mac systems. I will post an update very soon (I use the class on two websites and have this Mac problem too)

  22. Please check the updated post…

  23. I am trying to learn how to zip files and sub files, i am taking a class on Microsoft Office and one of my assignments are to create and zip a file and 3 subfiles can someone tell me how to do so

    thank you

  24. i have download whole public_html folder as zip file but it return internal server error because public_html contain hung number of file and folder

    So whats is better solution to download this

    Thank’s

  25. Hi, check my update about using the zip command line tool. It makes no sense to create a zip file while a PHP class.

Because of all the spam attemps I've decided to close the comment form at this time. If you have have any questions or comments please post them by using Google+ or Twitter (the links to my profiles are located at the top of this page).