PHP Zip:提取目录的内容

Posted

技术标签:

【中文标题】PHP Zip:提取目录的内容【英文标题】:PHP Zip: Extract contents of a directory 【发布时间】:2013-07-31 22:13:57 【问题描述】:

我需要将 zip 存档中目录的内容提取到输出目录中。

zip 中的目录名称可以是任何名称。但是,它将是 zip 存档基础中的唯一目录。不过,在 zip 存档中,目录中可能有任意数量的文件。

zip 中的文件结构如下:

- d0001
  - My Folder
    - view.php
    - tasks.txt
  - file1.txt
  - picture1.png
  - document.doc

输出目录的内容需要如下所示:

- My Folder
  - view.php
  - tasks.txt
- file1.txt
- picture1.png
- document.doc

我目前拥有的代码删除了输出目录的内容,并将整个 zip 存档解压到该目录中:

function Unzip($source, $destination) 
    $zip = new ZipArchive;
    $res = $zip->open($source);
    if($res === TRUE) 
      $zip->extractTo($destination);
      $zip->close();
      return true;
     else 
      return false;
    

function rrmdir($dir, $removebase = true) 
    if(is_dir($dir)) 
        $objects = scandir($dir);
        foreach($objects as $object) 
            if($object != "." && $object != "..") 
                if(filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
            
        
        reset($objects);
        if($removebase == true)
          rmdir($dir);
    


$filename = '/home/files.zip';
$dest = '/home/myfiles/';

if(is_dir($dest)) 
  rrmdir($dest, false);

  $unzip = Unzip($filename, $dest);
  if($unzip === true) 
    echo 'Success';
   else
    echo 'Extraction of zip failed.';
 else
  echo 'The output directory does not exist!';

rrmdir() 所做的所有功能都是删除输出目录的内容。

【问题讨论】:

【参考方案1】:

我设法通过手动处理文件流而不是使用extractTo() 来让它工作。

该脚本将存档基础中的所有文件以及存档基础目录中的所有文件提取到输出文件夹中。

例如,如果这是档案内容:

- d0001
  - My Folder
    - view.php
    - tasks.txt
  - file1.txt
  - picture1.png
  - document.doc
- d2
  - another1.png
  - pic2.gif
- doc1.txt
- mylist.txt

输出目录的内容如下所示:

- My Folder
  - view.php
  - tasks.txt
- file1.txt
- picture1.png
- document.doc
- another1.png
- pic.gif
- doc1.txt
- mylist.txt

代码:

function rrmdir($dir, $removebase = true) 
    if(is_dir($dir)) 
        $objects = scandir($dir);
        foreach($objects as $object) 
            if($object != "." && $object != "..") 
                if(filetype($dir."/".$object) == "dir") rrmdir($dir."/".$object); else unlink($dir."/".$object);
            
        
        reset($objects);
        if($removebase == true)
          rmdir($dir);
    


$filename = '/home/files.zip';
$dest = '/home/myfiles/';

if(is_dir($dest)) 
  // Remove directory's contents
  rrmdir($dest, false);

  // Load up the zip
  $zip = new ZipArchive;
  $unzip = $zip->open($filename);
  if($unzip === true) 
    for($i=0; $i<$zip->numFiles; $i++) 
      $name = $zip->getNameIndex($i);

      // Remove the first directory in the string if necessary
      $parts = explode('/', $name);
      if(count($parts) > 1) 
        array_shift($parts);
      
      $file = $dest . '/' . implode('/', $parts);

      // Create the directories if necessary
      $dir = dirname($file);
      if(!is_dir($dir))
        mkdir($dir, 0777, true);

      // Check if $name is a file or directory
      if(substr($file, -1) == "/") 
        // $name is a directory
        // Create the directory
        if(!is_dir($file))
          mkdir($file, 0777, true);
       else 
        // $name is a file
        // Read from Zip and write to disk
        $fpr = $zip->getStream($name);
        $fpw = fopen($file, 'w');
        while($data = fread($fpr, 1024)) 
          fwrite($fpw, $data);
        
        fclose($fpr);
        fclose($fpw);
      
    
    echo 'Success';
   else
    echo 'Extraction of zip failed.';
 else
  echo 'The output directory does not exist!';

【讨论】:

以上是关于PHP Zip:提取目录的内容的主要内容,如果未能解决你的问题,请参考以下文章

在 PHP 中是不是可以在不先提取其内容的情况下检查 Zip 文件的内容?

将zip内容提取到与zip文件同名的目录中,保留目录结构[关闭]

PHP提取zip [重复]

使用 Python 将 zip 文件和嵌套的 zip 文件提取到目标目录中

php zip提取使文件为空

将 zip 文件的内容作为 StorageFile 对象读取而不提取?