Manipulate Zip Files with PHP
Published: 04/06/2009
Programming, Code
Back in the olden days the easiest way to create zip files using php was to have the operating system (OS) do it. Sure, there were modules you could compile php with but really affected portability. So using the OS wasn’t too big of an issue but it still wasn’t optimal.
The Old Way
Assuming the OS was Linux, and if you were doing php web development it probably was, you’d execute a call like the below to create a gzipped archive:
<?php exec(tar cfvz ".$WhereBackup."/".$Name.".tar.gz ".$whatBackup."); ?>
The above sucks for a couple reasons. For one, it requires a pretty large security hole to not be plugged; exec allows piping commands to the OS directly. For another, the above method will only work on Linux; Windows doesn’t have a “tar” command.
The biggest reason the above sucked, for me at least, was that the layman doesn’t understand the tar.gz file extension. I can’t count the number of times I’ve had to explain to a client or colleague that tar.gz is, as far as their needs go, that tar.gz is ok. “You can open it in WinZip or WinRar.”, I’d say. Sigh…
Enter PclZip
PclZip is a php class that creates and manage ZIP formatted archives. PclZip works on both Windows and Linux and is pretty easy to use. There’s a pretty extensive user manual too.
I first heard about it while writing the WordPress plugin iTunes-Data. I wanted to allow the upload of the iTunes XML files but mine was over 10MB so testing was becoming… inconvenient. I knew WordPress could manipulate zip archives so I took a look under the hood and the was PclZip.
Anyway, you can create zip files, remove files from existing zip files and extract zip files using the PclZip class. Below are a couple examples of how to do each.
The Basics
The most important thing to know about using PclZip is that the PclZip object must be instantiated with a “.zip” file being passed. It doesn’t matter if you’re creating, extracting or modifying, you have to pass the file you want to manipulate before you do anything else.
<?php require_once('pclzip.lib.php'); $archive = new PclZip('tmp/archive.zip'); ?>
Optional Arguments
PclZip allows for detailed control over archives through the use of optional arguments that get passed at the tail end of functions. According to the official site:
The optional arguments are identified by a name, which is in reality a static integer value. The value of the argument can be a single value or a list of values. In some cases they does not take a value, their name is enought to indicate a specific action to the method.
There’s far too many arguments you can use so I won’t bother listing them all here but there’s a complete list at the end of the article.
Create a Zip File
To create a zip file you have to pass the name of the archive you want to create to the object. The file passed will be where to the archive will be created.
You can include multiple files by either passing the directory, if you want the entire directory or by using a couple different methods to pass individual files and directories; arrays or a csv string.
<?php require_once('pclzip.lib.php'); $archive = new PclZip('tmp/archive.zip'); //includes the file "debug.cl" and the directory "logs" $files = './debug.cl,./logs/'; if ($archive->create($files) == 0) { die('Error : '.$archive->errorInfo(true)); } ?>
or
<?php require_once('pclzip.lib.php'); $archive = new PclZip('tmp/archive.zip'); //same as above $files = array('./debug.cl','./logs/'); if ($archive->create($files) == 0) { die('Error : '.$archive->errorInfo(true)); } ?>
Extracting Files from Archive
There are quite a few options for extracting files from a zip archive. PclZip contains a pretty extensive filtering mechanism that allows for some pretty selective extractions.
By default when extracting the files from an archive PclZip puts the files relative to where the script is executed.
$archive = new PclZip('tmp/archive.zip'); if ($archive->extract() == 0) { die("Error : ".$archive->errorInfo(true)); }
You can explicitly state where the archive files are extracted by setting a value to the “PCLZIP_OPT_PATH” parameter. The below extracts all the files to the “./tmp” directory:
$archive = new PclZip('tmp/archive.zip'); if ($archive->extract(PCLZIP_OPT_PATH, "./tmp") == 0) { die("Error : ".$archive->errorInfo(true)); }
Optional Argument List
PCLZIP_OPT_PATH
PCLZIP_OPT_ADD_PATH
PCLZIP_OPT_REMOVE_PATH
PCLZIP_OPT_REMOVE_ALL_PATH
PCLZIP_OPT_SET_CHMOD
PCLZIP_OPT_BY_NAME
PCLZIP_OPT_BY_EREG
PCLZIP_OPT_BY_PREG
PCLZIP_OPT_BY_INDEX
PCLZIP_OPT_EXTRACT_AS_STRING
PCLZIP_OPT_EXTRACT_IN_OUTPUT
PCLZIP_OPT_NO_COMPRESSION
PCLZIP_OPT_COMMENT
PCLZIP_OPT_ADD_COMMENT
PCLZIP_OPT_PREPEND_COMMENT
PCLZIP_OPT_REPLACE_NEWER
PCLZIP_OPT_EXTRACT_DIR_RESTRICTION
PCLZIP_OPT_ADD_TEMP_FILE_ON
PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD
PCLZIP_OPT_ADD_TEMP_FILE_OFF