All formats

ZipArchive

LanguagePHP
LicensePHP License (extension), BSD 3-clause (libzip)
Repositorygithub.com/pierrejoye/php_zip (also bundled in php-src)
Documentationphp.net: ZipArchive
Depends onlibzip
Read / writeyes / yes, ZIP64, stored, DEFLATE, and bzip2 / LZMA / XZ / Zstandard if libzip has them; AES and ZipCrypto

ZipArchive is the class of the zip extension, a wrapper around libzip. It opens an archive, collects changes (add, rename, delete, set comment, set encryption) and writes them when you call close(). Most PHP builds and distributions include the extension.

Like libzip, it modifies archives by writing a new file on close(); a large archive needs free disk space for the temporary copy.

Installation#

Shell
# Debian / Ubuntu
sudo apt install php-zip
# Fedora
sudo dnf install php-pecl-zip
# compile PHP with
./configure --with-zip

On Windows, enable extension=zip in php.ini. Check with php -m | grep zip.

Basic usage: extract and create a ZIP#

PHP
<?php
$zip = new ZipArchive();

// extract
if ($zip->open('in.zip') !== true) {
    die("cannot open in.zip\n");
}
$zip->extractTo('out');
$zip->close();

// create
if ($zip->open('out.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
    die("cannot create out.zip\n");
}
$zip->addFile('report.pdf', 'docs/report.pdf');
$zip->addFromString('hello.txt', "hello from PHP\n");
$zip->close();  // the archive is written here

open() returns true or an error code (ZipArchive::ER_NOENT, ER_NOZIP, …), so compare with !== true.

How to list the files in a ZIP#

PHP
<?php
$zip = new ZipArchive();
$zip->open('in.zip', ZipArchive::RDONLY);
for ($i = 0; $i < $zip->numFiles; $i++) {
    $st = $zip->statIndex($i);
    printf("%-40s %10d -> %10d  %s\n", $st['name'], $st['size'], $st['comp_size'], date('Y-m-d H:i', $st['mtime']));
}
$zip->close();

How to read one file from a ZIP#

PHP
<?php
$zip = new ZipArchive();
$zip->open('in.zip', ZipArchive::RDONLY);
$text = $zip->getFromName('docs/readme.txt');  // false if missing
if ($text !== false) {
    echo $text;
}

// stream a large entry
$fp = $zip->getStream('data/big.csv');
while (($line = fgets($fp)) !== false) {
    // process $line
}
fclose($fp);
$zip->close();

Without opening the archive first, the zip:// stream wrapper reads one entry: file_get_contents('zip://in.zip#docs/readme.txt').

How to zip a whole folder#

PHP
<?php
$zip = new ZipArchive();
$zip->open('photos.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addGlob('photos/*.jpg', 0, ['remove_all_path' => true]);
// recursive: walk the directory yourself
$it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('docs', FilesystemIterator::SKIP_DOTS));
foreach ($it as $file) {
    $zip->addFile($file->getPathname(), str_replace('\\', '/', $file->getPathname()));
}
$zip->close();

How to create and extract an AES-encrypted ZIP#

PHP
<?php
$zip = new ZipArchive();
$zip->open('secret.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
$zip->addFromString('secret.txt', 'top secret');
$zip->setEncryptionName('secret.txt', ZipArchive::EM_AES_256, 'my password');
$zip->close();

$zip->open('secret.zip');
$zip->setPassword('my password');
$zip->extractTo('out');
$zip->close();

How to set the compression method#

PHP
$zip->addFile('data.csv');
$zip->setCompressionName('data.csv', ZipArchive::CM_DEFLATE, 9);
// ZipArchive::CM_STORE for already compressed files;
// CM_ZSTD, CM_XZ, CM_LZMA, CM_BZIP2 if ZipArchive::isCompressionMethodSupported() says so

Tips#