Delicious Bookmark this on Delicious Share on Facebook SlashdotSlashdot It! Digg! Digg



PHP : Function Reference : Zip File Functions : zip_open

zip_open

Open a ZIP file archive (PHP 4 >= 4.0.7, PHP 5 >= 5.2.0, PECL zip:1.0-1.9.0)
mixed zip_open ( string filename )


Code Examples / Notes » zip_open

robert

The zip_entry_read above is wrong.  Since the file was opened with popen, you have to read the file in chunks, so zip_entry_read should read:
function zip_entry_read(&$res, $nbytes)
{
   $contents = '';
   while (!feof($res['fp'])) {
       $contents .= fread($res['fp'], 8192);
   }
   return $contents;
}
Otherwise, it was a very useful library.  Thanks!


saulius

Some older PHP versions used to return false if zip_open failed, and newer versions return the number of error (as integer), so instead of this:
$zip = zip_open($zip_file);
if ($zip) {
 // consider zip file opened successfully
}
use this:
$zip = zip_open($zip_file);
if (is_resource($zip)) {
 // consider zip file opened successfully
}
You may also use this function to get the error message by it's number:
function zipFileErrMsg($errno) {
 // using constant name as a string to make this function PHP4 compatible
 $zipFileFunctionsErrors = array(
   'ZIPARCHIVE::ER_MULTIDISK' => 'Multi-disk zip archives not supported.',
   'ZIPARCHIVE::ER_RENAME' => 'Renaming temporary file failed.',
   'ZIPARCHIVE::ER_CLOSE' => 'Closing zip archive failed',
   'ZIPARCHIVE::ER_SEEK' => 'Seek error',
   'ZIPARCHIVE::ER_READ' => 'Read error',
   'ZIPARCHIVE::ER_WRITE' => 'Write error',
   'ZIPARCHIVE::ER_CRC' => 'CRC error',
   'ZIPARCHIVE::ER_ZIPCLOSED' => 'Containing zip archive was closed',
   'ZIPARCHIVE::ER_NOENT' => 'No such file.',
   'ZIPARCHIVE::ER_EXISTS' => 'File already exists',
   'ZIPARCHIVE::ER_OPEN' => 'Can\'t open file',
   'ZIPARCHIVE::ER_TMPOPEN' => 'Failure to create temporary file.',
   'ZIPARCHIVE::ER_ZLIB' => 'Zlib error',
   'ZIPARCHIVE::ER_MEMORY' => 'Memory allocation failure',
   'ZIPARCHIVE::ER_CHANGED' => 'Entry has been changed',
   'ZIPARCHIVE::ER_COMPNOTSUPP' => 'Compression method not supported.',
   'ZIPARCHIVE::ER_EOF' => 'Premature EOF',
   'ZIPARCHIVE::ER_INVAL' => 'Invalid argument',
   'ZIPARCHIVE::ER_NOZIP' => 'Not a zip archive',
   'ZIPARCHIVE::ER_INTERNAL' => 'Internal error',
   'ZIPARCHIVE::ER_INCONS' => 'Zip archive inconsistent',
   'ZIPARCHIVE::ER_REMOVE' => 'Can\'t remove file',
   'ZIPARCHIVE::ER_DELETED' => 'Entry has been deleted',
 );
 $errmsg = 'unknown';
 foreach ($zipFileFunctionsErrors as $constName => $errorMessage) {
   if (defined($constName) and constant($constName) === $errno) {
     return 'Zip File Function error: '.$errorMessage;
   }
 }
 return 'Zip File Function error: unknown';
}
$zip = zip_open($zip_file);
if (!is_resource($zip)) {
 die(zipFileErrMsg($zip));
}


bisqwit

If your PHP installation does not have the zip_open function, and you can't install it for whatever reason, you can use these functions instead, if the server has access to the "unzip" utility (most Linux systems do).
So far I have tested these only in Fedora Core 3.
Use at your own risk.
<?php
function ShellFix($s)
{
 return "'".str_replace("'", "'\''", $s)."'";
}
function zip_open($s)
{
 $fp = @fopen($s, 'rb');
 if(!$fp) return false;
 
 $lines = Array();
 $cmd = 'unzip -v '.shellfix($s);
 exec($cmd, $lines);
 
 $contents = Array();
 $ok=false;
 foreach($lines as $line)  
 {
   if($line[0]=='-') { $ok=!$ok; continue; }
   if(!$ok) continue;
   
   $length = (int)$line;
   $fn = trim(substr($line,58));
   
   $contents[] = Array('name' => $fn, 'length' => $length);
 }
 
 return
   Array('fp'       => $fp,  
         'name'     => $s,
         'contents' => $contents,
         'pointer'  => -1);
}                          
function zip_read(&$fp)
{
 if(!$fp) return false;
 
 $next = $fp['pointer'] + 1;
 if($next >= count($fp['contents'])) return false;

 $fp['pointer'] = $next;
 return $fp['contents'][$next];
}
function zip_entry_name(&$res)
{
 if(!$res) return false;
 return $res['name'];
}                          
function zip_entry_filesize(&$res)
{
 if(!$res) return false;
 return $res['length'];
}
function zip_entry_open(&$fp, &$res)
{
 if(!$res) return false;
 $cmd = 'unzip -p '.shellfix($fp['name']).' '.shellfix($res['name']);
 
 $res['fp'] = popen($cmd, 'r');
 return !!$res['fp'];  
}
function zip_entry_read(&$res, $nbytes)
{
 return fread($res['fp'], $nbytes);
}
function zip_entry_close(&$res)
{
 fclose($res['fp']);
 unset($res['fp']);
}
function zip_close(&$fp)
{
 fclose($fp['fp']);
}
?>


michael

I tried the replacement hack above on Windows2k, here
are some fixes needed:
replace:
 return "'".str_replace("'", "'\''", $s)."'";
with:
 return '"'.str_replace("'", "'\''", $s).'"';
replace:
if($line[0]=='-') { $ok=!$ok; continue; }
with:
if($line[2]=='-') { $ok=!$ok; continue; }
replace:
$contents[] = Array('name' => $fn, 'length' => $length);
with:
  array_push($contents, Array('name' => $fn, 'length' => $length));


barbarinasv

Function zip_entry_read() written by "bisqwit at iki dot fi" has to be modified to read entire files:
<?php
function zip_entry_read(&$res, $nbytes) {
while (!feof($res['fp'])) {
$contents .= fread($res['fp'], $nbytes);
}
return $contents;
}
?>


ponsho

For bisqwit at iki dot fi solution of alternative functions there's just one problem when trying to read the file thats because some bug in fread when handling from popen so it just load 8192 bytes here's the function corrected.
<?php
   function zip_entry_read(&$res, $nbytes)
   {
    while ($s = fgets($res['fp'],1024)) {
    $data  .= $s;
    }
     return $data;
   }
?>


flominator

@bisqwit at iki dot fi: If you're using older versions of PHP this skript might only read the first 8192 bytes. Great thing, anyway!

Change Language


Follow Navioo On Twitter
zip_close
zip_entry_close
zip_entry_compressedsize
zip_entry_compressionmethod
zip_entry_filesize
zip_entry_name
zip_entry_open
zip_entry_read
zip_open
zip_read
ZipArchive::addEmptyDir
ZipArchive::addFile
ZipArchive::addFromString
ZipArchive::close
ZipArchive::deleteIndex
ZipArchive::deleteName
ZipArchive::extractTo
ZipArchive::getArchiveComment
ZipArchive::getCommentIndex
ZipArchive::getCommentName
ZipArchive::getFromIndex
ZipArchive::getFromName
ZipArchive::getNameIndex
ZipArchive::getStream
ZipArchive::locateName
ZipArchive::open
ZipArchive::renameIndex
ZipArchive::renameName
ZipArchive::setArchiveComment
ZipArchive::setCommentIndex
ZipArchive::setCommentName
ZipArchive::statIndex
ZipArchive::statName
ZipArchive::unchangeAll
ZipArchive::unchangeArchive
ZipArchive::unchangeIndex
ZipArchive::unchangeName
eXTReMe Tracker