Zip a folder (include itself).
Usage:
HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
<?php
class HZip
{
/**
* Add files and sub-directories in a folder to zip file.
* @param string $folder
* @param ZipArchive $zipFile
* @param int $exclusiveLength Number of text to be exclusived from the file path.
*/
private static function folderToZip($folder, &$zipFile, $exclusiveLength) {
$handle = opendir($folder);
while ($f = readdir($handle)) {
if ($f != '.' && $f != '..') {
$filePath = "$folder/$f";
// Remove prefix from file path before add to zip.
$localPath = substr($filePath, $exclusiveLength);
if (is_file($filePath)) {
$zipFile->addFile($filePath, $localPath);
} elseif (is_dir($filePath)) {
// Add sub-directory.
$zipFile->addEmptyDir($localPath);
self::folderToZip($filePath, $zipFile, $exclusiveLength);
}
}
}
closedir($handle);
}
/**
* Zip a folder (include itself).
* Usage:
* HZip::zipDir('/path/to/sourceDir', '/path/to/out.zip');
*
* @param string $sourcePath Path of directory to be zip.
* @param string $outZipPath Path of output zip file.
*/
public static function zipDir($sourcePath, $outZipPath)
{
$pathInfo = pathInfo($sourcePath);
$parentPath = $pathInfo['dirname'];
$dirName = $pathInfo['basename'];
$z = new ZipArchive();
$z->open($outZipPath, ZIPARCHIVE::CREATE);
$z->addEmptyDir($dirName);
self::folderToZip($sourcePath, $z, strlen("$parentPath/"));
$z->close();
}
}
?>
The ZipArchive class
(No version information available, might only be in SVN)
Introduction
A file archive, compressed with Zip.
Class synopsis
ZipArchive
{
/* Properties */
/* Methods */
bool addFile
( string
}$filename
[, string $localname = NULL
[, int $start = 0
[, int $length = 0
]]] )Properties
- status
-
Status of the Zip Archive
- statusSys
-
System status of the Zip Archive
- numFiles
-
Number of files in archive
- filename
-
File name in the file system
- comment
-
Comment for the archive
Table of Contents
- ZipArchive::addEmptyDir — Add a new directory
- ZipArchive::addFile — Adds a file to a ZIP archive from the given path
- ZipArchive::addFromString — Add a file to a ZIP archive using its contents
- ZipArchive::close — Close the active archive (opened or newly created)
- ZipArchive::deleteIndex — delete an entry in the archive using its index
- ZipArchive::deleteName — delete an entry in the archive using its name
- ZipArchive::extractTo — Extract the archive contents
- ZipArchive::getArchiveComment — Returns the Zip archive comment
- ZipArchive::getCommentIndex — Returns the comment of an entry using the entry index
- ZipArchive::getCommentName — Returns the comment of an entry using the entry name
- ZipArchive::getFromIndex — Returns the entry contents using its index
- ZipArchive::getFromName — Returns the entry contents using its name
- ZipArchive::getNameIndex — Returns the name of an entry using its index
- ZipArchive::getStatusString — Returns the status error message, system and/or zip messages
- ZipArchive::getStream — Get a file handler to the entry defined by its name (read only).
- ZipArchive::locateName — Returns the index of the entry in the archive
- ZipArchive::open — Open a ZIP file archive
- ZipArchive::renameIndex — Renames an entry defined by its index
- ZipArchive::renameName — Renames an entry defined by its name
- ZipArchive::setArchiveComment — Set the comment of a ZIP archive
- ZipArchive::setCommentIndex — Set the comment of an entry defined by its index
- ZipArchive::setCommentName — Set the comment of an entry defined by its name
- ZipArchive::statIndex — Get the details of an entry defined by its index.
- ZipArchive::statName — Get the details of an entry defined by its name.
- ZipArchive::unchangeAll — Undo all changes done in the archive
- ZipArchive::unchangeArchive — Revert all global changes done in the archive.
- ZipArchive::unchangeIndex — Revert all changes done to an entry at the given index
- ZipArchive::unchangeName — Revert all changes done to an entry with the given name.
umbalaconmeogia at NOSPAM dot gmail dot com ¶
5 months ago
hardcorevenom at gmx dot com ¶
2 years ago
Read a file from an archive to a variable.
A warning is printed automatically in case of a CRC32 mismatch, which we capture, so we can print our own error message.
<?php
$zip = new ZipArchive();
if ($zip->open('archive.zip')) {
$fp = $zip->getStream('myfile.txt'); //file inside archive
if(!$fp)
die("Error: can't get stream to zipped file");
$stat = $zip->statName('myfile.txt');
$buf = ""; //file buffer
ob_start(); //to capture CRC error message
while (!feof($fp)) {
$buf .= fread($fp, 2048); //reading more than 2156 bytes seems to disable internal CRC32 verification (bug?)
}
$s = ob_get_contents();
ob_end_clean();
if(stripos($s, "CRC error") != FALSE){
echo 'CRC32 mismatch, current ';
printf("%08X", crc32($buf)); //current CRC
echo ', expected ';
printf("%08X", $stat['crc']); //expected CRC
}
fclose($fp);
$zip->close();
//Done, unpacked file is stored in $buf
}
?>
To create a corrupt file, change a byte in a zip file using a hex editor.
panique at web dot de ¶
9 months ago
Important: Due to the natural file size limit of 4GB (~3,6GB to be correct) of zip files, this class will generate corrupt files of the result is larger than 4 GB. Using tar.gz is a proper alternative.
bruno dot vibert at bonobox dot fr ¶
11 months ago
There is a usefull function to get the ZipArchive status as a human readable string :
<?php
function ZipStatusString( $status )
{
switch( (int) $status )
{
case ZipArchive::ER_OK : return 'N No error';
case ZipArchive::ER_MULTIDISK : return 'N Multi-disk zip archives not supported';
case ZipArchive::ER_RENAME : return 'S Renaming temporary file failed';
case ZipArchive::ER_CLOSE : return 'S Closing zip archive failed';
case ZipArchive::ER_SEEK : return 'S Seek error';
case ZipArchive::ER_READ : return 'S Read error';
case ZipArchive::ER_WRITE : return 'S Write error';
case ZipArchive::ER_CRC : return 'N CRC error';
case ZipArchive::ER_ZIPCLOSED : return 'N Containing zip archive was closed';
case ZipArchive::ER_NOENT : return 'N No such file';
case ZipArchive::ER_EXISTS : return 'N File already exists';
case ZipArchive::ER_OPEN : return 'S Can\'t open file';
case ZipArchive::ER_TMPOPEN : return 'S Failure to create temporary file';
case ZipArchive::ER_ZLIB : return 'Z Zlib error';
case ZipArchive::ER_MEMORY : return 'N Malloc failure';
case ZipArchive::ER_CHANGED : return 'N Entry has been changed';
case ZipArchive::ER_COMPNOTSUPP : return 'N Compression method not supported';
case ZipArchive::ER_EOF : return 'N Premature EOF';
case ZipArchive::ER_INVAL : return 'N Invalid argument';
case ZipArchive::ER_NOZIP : return 'N Not a zip archive';
case ZipArchive::ER_INTERNAL : return 'N Internal error';
case ZipArchive::ER_INCONS : return 'N Zip archive inconsistent';
case ZipArchive::ER_REMOVE : return 'S Can\'t remove file';
case ZipArchive::ER_DELETED : return 'N Entry has been deleted';
default: return sprintf('Unknown status %s', $status );
}
}
?>
h-fate at gmx dot net ¶
2 years ago
Be wary that there are several algorithms to generate a zip file. I found that Office OpenXML files created with ZipArchive are not recognized by Excel 2007, for example.
You have to use a different class to zip in this case, such as PclZip.
Jerry dot Saravia at emc dot com ¶
1 year ago
The following code can be used to get a list of all the file names in a zip file.
<?php
$za = new ZipArchive();
$za->open('theZip.zip');
for( $i = 0; $i < $za->numFiles; $i++ ){
$stat = $za->statIndex( $i );
print_r( basename( $stat['name'] ) . PHP_EOL );
}
?>
webmaster at sebastiangrinke dot info ¶
1 year ago
Here is a simple function which zips folders with all sub folders or only a simple file... the $data var can be a string or an array...
<?php
public function un_zip($data,$arcpf,$mode='zip',$obj=''){
$absoluterpfad = 'YOUR_BASE_PATH';
$arcpf = $absoluterpfad.DS.$arcpf;
if(is_object($obj)==false){
$archiv = new ZipArchive();
$archiv->open($arcpf,ZipArchive::CREATE);
}else{$archiv =& $obj;}
if($mode=='zip'){
if(is_array($data)==true){
foreach($data as $dtmp){
$archiv =& un_zip($dtmp,$arcpf,'zip',&$archiv);
}
}else{
if(is_dir($data)==true){
$archiv->addEmptyDir(str_replace($absoluterpfad.DS,'',$data));
$files = scandir($data);
$bad = array('.','..');
$files = array_diff($files,$bad);
foreach($files as $ftmp){
if(is_dir($data.DS.$ftmp)==true){
$archiv->addEmptyDir(str_replace($absoluterpfad.DS,'',$data.'/'.$ftmp));
$archiv =& un_zip($data.DS.$ftmp,$arcpf,'zip',&$archiv);
}elseif(is_file($data.DS.$ftmp)==true){
$archiv->addFile($data.DS.$ftmp,str_replace($absoluterpfad.DS,'',$data.'/'.$ftmp));
}
}
}elseif(is_file($data)==true){$archiv->addFile($data,str_replace($absoluterpfad.DS,'',$data));}
}
}
if(is_object($obj)==false){$archiv->close();}
else{return $archiv;}
if($mode=='unzip'){$archiv->extractTo($data);}
}
?>
niklas dot schumi at NOSPAM dot googlemail dot com ¶
9 months ago
Hi there.
I just wrote a little function to zip a whole folder while maintaining the dir-structure. I hope it might help someone.
<?php
function folderToZip($folder, &$zipFile, $subfolder = null) {
if ($zipFile == null) {
// no resource given, exit
return false;
}
// we check if $folder has a slash at its end, if not, we append one
$folder .= end(str_split($folder)) == "/" ? "" : "/";
$subfolder .= end(str_split($subfolder)) == "/" ? "" : "/";
// we start by going through all files in $folder
$handle = opendir($folder);
while ($f = readdir($handle)) {
if ($f != "." && $f != "..") {
if (is_file($folder . $f)) {
// if we find a file, store it
// if we have a subfolder, store it there
if ($subfolder != null)
$zipFile->addFile($folder . $f, $subfolder . $f);
else
$zipFile->addFile($folder . $f);
} elseif (is_dir($folder . $f)) {
// if we find a folder, create a folder in the zip
$zipFile->addEmptyDir($f);
// and call the function again
folderToZip($folder . $f, $zipFile, $f);
}
}
}
}
?>
Use it like this:
<?php
$z = new ZipArchive();
$z->open("test.zip", ZIPARCHIVE::CREATE);
folderToZip("storeThisFolder", $z);
$z->close();
?>
Have a good day!
anonymous at example dot net ¶
1 year ago
status - libzip error code (ER_*)
statusSys - copy of errno (E*) or zlib error code
ER_OK N No error
ER_MULTIDISK N Multi-disk zip archives not supported
ER_RENAME S Renaming temporary file failed
ER_CLOSE S Closing zip archive failed
ER_SEEK S Seek error
ER_READ S Read error
ER_WRITE S Write error
ER_CRC N CRC error
ER_ZIPCLOSED N Containing zip archive was closed
ER_NOENT N No such file
ER_EXISTS N File already exists
ER_OPEN S Can't open file
ER_TMPOPEN S Failure to create temporary file
ER_ZLIB Z Zlib error
ER_MEMORY N Malloc failure
ER_CHANGED N Entry has been changed
ER_COMPNOTSUPP N Compression method not supported
ER_EOF N Premature EOF
ER_INVAL N Invalid argument
ER_NOZIP N Not a zip archive
ER_INTERNAL N Internal error
ER_INCONS N Zip archive inconsistent
ER_REMOVE S Can't remove file
ER_DELETED N Entry has been deleted
