PHP Zip:提取目录的内容

时间:2013-07-31 22:13:57

标签: php zip archive

我需要将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 个答案:

答案 0 :(得分:0)

我设法通过手动处理文件流而不是使用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!';