Zip
在线手册:中文  英文

ZipArchive

(PHP 5 >= 5.2.0, PECL zip >= 1.1.0)

简介

一个用 Zip 压缩的文件存档。

类摘要

ZipArchive {
/* 属性 */
/* 方法 */
bool addEmptyDir ( string $dirname )
bool addFile ( string $filename [, string $localname = NULL [, int $start = 0 [, int $length = 0 ]]] )
bool addFromString ( string $localname , string $contents )
bool close ( void )
bool deleteIndex ( int $index )
bool deleteName ( string $name )
bool extractTo ( string $destination [, mixed $entries ] )
string getArchiveComment ([ int $flags ] )
string getCommentIndex ( int $index [, int $flags ] )
string getCommentName ( string $name [, int $flags ] )
string getFromIndex ( int $index [, int $length = 0 [, int $flags ]] )
string getFromName ( string $name [, int $length = 0 [, int $flags ]] )
string getNameIndex ( int $index [, int $flags ] )
string getStatusString ( void )
resource getStream ( string $name )
int locateName ( string $name [, int $flags ] )
mixed open ( string $filename [, int $flags ] )
bool renameIndex ( int $index , string $newname )
bool renameName ( string $name , string $newname )
bool setArchiveComment ( string $comment )
bool setCommentIndex ( int $index , string $comment )
bool setCommentName ( string $name , string $comment )
array statIndex ( int $index [, int $flags ] )
array statName ( string $name [, int $flags ] )
bool unchangeAll ( void )
bool unchangeArchive ( void )
bool unchangeIndex ( int $index )
bool unchangeName ( string $name )
}

属性

status

Zip Archive 的状态

statusSys

Zip Archive 的系统状态

numFiles

压缩包里的文件数

filename

在文件系统里的文件名

comment

压缩包的注释

Table of Contents


Zip
在线手册:中文  英文

用户评论:

AshleyDambra at live dot com (2013-05-16 08:23:26)

Simple class xZip to zip big folders into multiple parts and unzip multi zip files at once.

<?php
class xZip {
    public function 
__construct() {}
    private function 
_rglobRead($source, &$array = array()) {
        if (!
$source || trim($source) == "") {
            
$source ".";
        }
        foreach ((array) 
glob($source "/*/") as $key => $value) {
            
$this->_rglobRead(str_replace("//""/"$value), $array);
        }
    
        foreach ((array) 
glob($source "*.*") as $key => $value) {
            
$array[] = str_replace("//""/"$value);
        }
    }
    private function 
_zip($array$part$destination) {
        
$zip = new ZipArchive;
        @
mkdir($destination0777true);
    
        if (
$zip->open(str_replace("//""/""{$destination}/partz{$part}.zip"), ZipArchive::CREATE)) {
            foreach ((array) 
$array as $key => $value) {
                
$zip->addFile($valuestr_replace(array("../""./"), NULL$value));
            }
            
$zip->close();
        }
    }
    public function 
zip($limit 500$source NULL$destination "./") {
        if (!
$destination || trim($destination) == "") {
            
$destination "./";
        }
    
        
$this->_rglobRead($source$input);
        
$maxinput count($input);
        
$splitinto = (($maxinput $limit) > round($maxinput $limit0)) ? round($maxinput $limit0) + round($maxinput $limit0);
    
        for(
$i 0$i $splitinto$i ++) {
            
$this->_zip(array_slice($input, ($i $limit), $limittrue), $i$destination);
        }
        
        unset(
$input);
        return;
    }
    public function 
unzip($source$destination) {
        @
mkdir($destination0777true);
    
        foreach ((array) 
glob($source "/*.zip") as $key => $value) {
            
$zip = new ZipArchive;
            if (
$zip->open(str_replace("//""/"$value)) === true) {
                
$zip->extractTo($destination);
                
$zip->close();
            }
        }
    }
    
    public function 
__destruct() {}
}

//$zip = new xZip;
//$zip->zip(500, "images/", "images_zip/");
//$zip->unzip("images_zip/", "images/");
?>

umbalaconmeogia at NOSPAM dot gmail dot com (2012-11-28 03:48:10)

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 (
false !== $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($outZipPathZIPARCHIVE::CREATE);
    
$z->addEmptyDir($dirName);
    
self::folderToZip($sourcePath$zstrlen("$parentPath/"));
    
$z->close();
  }
}
?>

niklas dot schumi at NOSPAM dot googlemail dot com (2012-08-02 10:44:42)

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!

panique at web dot de (2012-07-14 11:21:48)

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 (2012-05-09 20:21:32)

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 );
    }
}

?>

webmaster at sebastiangrinke dot info (2011-10-06 13:30:25)

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);}
    }
?>

Jerry dot Saravia at emc dot com (2011-08-08 13:57:06)

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_rbasename$stat['name'] ) . PHP_EOL );
}
?>

anonymous at example dot net (2011-07-28 23:18:15)

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

h-fate at gmx dot net (2010-10-05 04:17:12)

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.

hardcorevenom at gmx dot com (2010-06-15 15:17:07)

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($fp2048); //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.

易百教程