0

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()が行うのは、出力ディレクトリの内容を削除することだけです。

4

1 に答える 1

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!';
于 2013-07-31T23:20:13.040 に答える