文字

ZipArchive::extractTo

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

ZipArchive::extractToExtract the archive contents

说明

bool ZipArchive::extractTo ( string $destination [, mixed $entries ] )

Extract the complete archive or the given files to the specified destination.

参数

destination

Location where to extract the files.

entries

The entries to extract. It accepts either a single entry name or an array of names.

返回值

成功时返回 TRUE , 或者在失败时返回 FALSE

范例

Example #1 Extract all entries

<?php
$zip 
= new  ZipArchive ;
if (
$zip -> open ( 'test.zip' ) ===  TRUE ) {
    
$zip -> extractTo ( '/my/destination/dir/' );
    
$zip -> close ();
    echo 
'ok' ;
} else {
    echo 
'failed' ;
}
?>

Example #2 Extract two entries

<?php
$zip 
= new  ZipArchive ;
$res  $zip -> open ( 'test_im.zip' );
if (
$res  ===  TRUE ) {
    
$zip -> extractTo ( '/my/destination/dir/' , array( 'pear_item.gif' 'testfromfile.php' ));
    
$zip -> close ();
    echo 
'ok' ;
} else {
    echo 
'failed' ;
}
?>

用户评论:

[#1] stanislav dot eckert at vizson dot de [2014-12-17 04:03:35]

The extractTo() method does not offer any parameter to allow extracting files and folders recursively from another (parent) folder inside the ZIP archive. With the following method it is possible:

<?php
  
class my_ZipArchive extends ZipArchive
  
{
    public function 
extractSubdirTo($destination$subdir)
    {
      
$errors = array();

      
// Prepare dirs
      
$destination str_replace(array("/""\\"), DIRECTORY_SEPARATOR$destination);
      
$subdir str_replace(array("/""\\"), "/"$subdir);

      if (
substr($destinationmb_strlen(DIRECTORY_SEPARATOR"UTF-8") * -1) != DIRECTORY_SEPARATOR)
        
$destination .= DIRECTORY_SEPARATOR;

      if (
substr($subdir, -1) != "/")
        
$subdir .= "/";

      
// Extract files
      
for ($i 0$i $this->numFiles$i++)
      {
        
$filename $this->getNameIndex($i);

        if (
substr($filename0mb_strlen($subdir"UTF-8")) == $subdir)
        {
          
$relativePath substr($filenamemb_strlen($subdir"UTF-8"));
          
$relativePath str_replace(array("/""\\"), DIRECTORY_SEPARATOR$relativePath);

          if (
mb_strlen($relativePath"UTF-8") > 0)
          {
            if (
substr($filename, -1) == "/")  // Directory
            
{
              
// New dir
              
if (!is_dir($destination $relativePath))
                if (!@
mkdir($destination $relativePath0755true))
                  
$errors[$i] = $filename;
            }
            else
            {
              if (
dirname($relativePath) != ".")
              {
                if (!
is_dir($destination dirname($relativePath)))
                {
                  
// New dir (for file)
                  
@mkdir($destination dirname($relativePath), 0755true);
                }
              }

              
// New file
              
if (@file_put_contents($destination $relativePath$this->getFromIndex($i)) === false)
                
$errors[$i] = $filename;
            }
          }
        }
      }

      return 
$errors;
    }
  }
?>


Example:
<?php
  
echo "<pre>";

  
$zip = new my_ZipArchive();
  if (
$zip->open("test.zip") === TRUE)
  {
    
$errors $zip->extractSubdirTo("C:/output""folder/subfolder/");
    
$zip->close();

    echo 
'ok, errors: ' count($errors);
  }
  else
  {
    echo 
'failed';
  }
?>

[#2] jan dot polak at onmyway dot cz [2013-10-18 08:11:20]

Be careful about a adding filenames that start with a slash '/' to your zip archives and then extracting them by name:

<?php
$zip
->addFromString('/file.txt''file contents'); // adds file.txt to archive's root

$zip->extractTo('dir/to/extract/'); // works, creates dir/to/extract/file.txt
$zip->extractTo('dir/to/extract/''/file.txt'); // works

$zip->extractTo('dir/to/extract/''file.txt'); // fails
?>

[#3] sachinyadav at live dot com [2010-11-12 00:29:08]

This script will search for ".txt" file(any file name) inside test.zip archive. Suppose, 'example.txt' file is found then the script will copy 'example.txt' to "txt_files" directory and rename it to 'test.zip.txt' and will remove all the blank lines from 'test.zip.txt' and resave and will exit the loop without searching remaining entries. 
This script can be useful to extract .DIZ and GIF files to display ZIP archive details in your script.
<?php 
   $value
="test.zip"
   
$filename="zip_files/$value"
   
$zip = new ZipArchive;
     if (
$zip->open($filename) === true) {
      echo 
"Generating TEXT file.";
          for(
$i 0$i $zip->numFiles$i++) { 
             
$entry $zip->getNameIndex($i);
               if(
preg_match('#\.(txt)$#i'$entry))
                {
                
////This copy function will move the entry to the root of "txt_files" without creating any sub-folders unlike "ZIP->EXTRACTO" function.
                
copy('zip://'.dirname(__FILE__).'/zip_files/'.$value.'#'.$entry'txt_files/'.$value.'.txt'); 
                
$content file_get_contents("txt_files/$value.txt");
                
$newcontent preg_replace("/(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+/""\n"$content);
                
file_put_contents("txt_files/$value.txt""$newcontent");
                break;
                } 
              }  
             
$zip->close();
            }
    else{
         echo 
"ZIP archive failed";
        }
?>


enjoy PHP programming.
Sachin Yadav

[#4] php-dev at proneticas dot net [2010-11-07 23:22:01]

If you want to copy one file at a time and remove the folder name that is stored in the ZIP file, so you don't have to create directories from the ZIP itself, then use this snippet (basically collapses the ZIP file into one Folder).

<?php

$path 
'zipfile.zip'

$zip = new ZipArchive;
if (
$zip->open($path) === true) {
    for(
$i 0$i $zip->numFiles$i++) {
        
$filename $zip->getNameIndex($i);
        
$fileinfo pathinfo($filename);
        
copy("zip://".$path."#".$filename"/your/new/destination/".$fileinfo['basename']);
    }                   
    
$zip->close();                   
}

?>


* On a side note, you can also use $_FILES['userfile']['tmp_name'] as the $path for an uploaded ZIP so you never have to move it or extract a uploaded zip file.

Cheers!

ProNeticas Dev Team

[#5] quake2005 at gmail dot com [2010-08-20 11:05:51]

If you want to extract one file at a time, you can use this:

<?php

$path 
'zipfile.zip'

$zip = new ZipArchive;
if (
$zip->open($path) === true) {
                    
    for(
$i 0$i $zip->numFiles$i++) {
                         
        
$zip->extractTo('path/to/extraction/', array($zip->getNameIndex($i)));
                        
        
// here you can run a custom function for the particular extracted file
                        
    
}
                    
    
$zip->close();
                    
}

?>

[#6] cory dot mawhorter at ephective dot com [2010-04-18 13:28:26]

This function will flatten a zip file using the ZipArchive class.  

It will extract all the files in the zip and store them in a single destination directory.  That is, no sub-directories will be created.

If anyone knows a better way to determine if an entry is a directory, please chime in.  I feel dirty checking for a trailing slash.

<?php
// dest shouldn't have a trailing slash
function zip_flatten $zipfile$dest='.' )
{
    
$zip = new ZipArchive;
    if ( 
$zip->open$zipfile ) ) 
    {
        for ( 
$i=0$i $zip->numFiles$i++ ) 
        {
            
$entry $zip->getNameIndex($i);
            if ( 
substr$entry, -) == '/' ) continue; // skip directories
            
            
$fp $zip->getStream$entry );
            
$ofp fopen$dest.'/'.basename($entry), 'w' );
            
            if ( ! 
$fp 
                throw new 
Exception('Unable to extract the file.');
            
            while ( ! 
feof$fp ) ) 
                
fwrite$ofpfread($fp8192) );
            
            
fclose($fp);
            
fclose($ofp);
        }

                
$zip->close();
    }
    else
        return 
false;
    
    return 
$zip;
}


?>


[EDIT BY danbrown AT php DOT net: Added $zip-close() per indication by original poster in follow-up note on 18-APR-2010.]

[#7] Anonymous [2009-12-02 16:38:37]

I am using this function to extract a specific folder and it's contents from a zip file:

<?php
function extractDir($zipfile$path) {
  if (
file_exists($zipfile)) {
    
$files = array();
    
$zip = new ZipArchive;
    if (
$zip->open($zipfile) === TRUE) {
      for(
$i 0$i $zip->numFiles$i++) {
        
$entry $zip->getNameIndex($i);
        
//Use strpos() to check if the entry name contains the directory we want to extract
        
if (strpos($entry"/MyFolder/")) {
          
//Add the entry to our array if it in in our desired directory
          
$files[] = $entry;
        }
      }
      
//Feed $files array to extractTo() to get only the files we want
      
if ($zip->extractTo($path$files) === TRUE) {
        return 
TRUE;
      } else {
        return 
FALSE;
      }
      
$zip->close();
    } else {
      return 
FALSE;
    }
  } else {
    return 
FALSE;
  }
}

//Run the function
if (extractDir($zipfile$path)) {
  
$extracted "YES! :-D";
} else {
  
$extracted "NO! :*(";
}

echo 
$extracted;
?>

[#8] kawzaki at yahoo dot com [2009-05-31 21:28:05]

Please be aware of the fact that using this function has OVERWRITE true.

an old file will be overwritten if the achieve (zipped file) contains file matching the same old file name.

old files that has no match in the zip, will be kept as is.

hopefully the someone will explain how to avoid overwriting old files.

[#9] Anonymous [2009-04-02 13:50:52]

I found it useful to add this to a function.

<?php

function zip_extract($file$extractPath) {

    
$zip = new ZipArchive;
    
$res $zip->open($file);
    if (
$res === TRUE) {
        
$zip->extractTo($extractPath);
        
$zip->close();
        return 
TRUE;
    } else {
        return 
FALSE;
    }

// end function
?>

[#10] Kaya [2008-10-03 01:36:01]

Make attention when using this function with apache & windows system. Windows file system use \  (backslash) instead of unix / (slash)
Use str_replace like this.
<?php
$zip 
= new ZipArchive;
    if (
$zip->open("file.zip")){
        
$path getcwd() . "/dirToextract/";
        
$path str_replace("\\","/",$path);
        echo 
$path;
        echo 
$zip->extractTo($path);
        
$zip->close();
        echo 
'Done.';
    } else {
        echo 
"Error";
    }
?>

[#11] tBone [2008-06-02 17:03:18]

This function, at least from my experience, maintains/forces the directory structure within the ZIP file.

ie. if you have FOLDER1/File1.txt in the zip file and you use
$zip->extractTo('/extract', 'FOLDER1/File1.txt');
the location of the extracted file will be:
/extract/FOLDER1/File1.txt

[#12] DerkaDerka [2007-03-05 22:48:12]

This function will overwrite destination files with the same name.

上一篇: 下一篇: