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.

Zip Files

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