如何排除要用ZipArchive或RecursiveDirectoryIterator压缩的文件和目录?

时间:2018-09-30 05:05:35

标签: php

我如何排除要添加到我的zip文件中的目录或特定文件,现在它仅在文件的直接父级位于exclude_files数组内部时才起作用,但是如果存在多个子级别,则会添加这些文件,并按默认情况下会创建父目录(排除的目录),因此最后,我拥有了所有文件夹,包括不需要的文件夹。

    /** Lets say we have */
    $this->excluded_files = ['.git','migrations'];


    /** Recursive generation */
    $iterator = new RecursiveDirectoryIterator($directory);
    // skip dot files while iterating 
    $iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);

    $files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);

    foreach ($files as $file) {
      if (is_dir($file) && !in_array(pathinfo($file , PATHINFO_DIRNAME), $this->excluded_files)) {

        $file = str_replace($directory, '', $file);

        /** Adding folder to zip file */
        $this->zip->addEmptyDir($file);

      } elseif (is_file($file) && !in_array(basename($file), $this->excluded_files)) {

        /** Adding file to zip */
        $this->zip->addFromString(str_replace($directory, '', $file), file_get_contents($file));

      }
      /** anything else will we skipped */
    }

    return $this;

1 个答案:

答案 0 :(得分:0)

问题出在她身上

basename($file)
  

basename —返回路径的结尾名称部分

这将在第二种情况下返回文件名而不是父目录,您应该像对待目录一样处理它,如下所示:-

pathinfo($file , PATHINFO_DIRNAME)

或者您可以使用内部Iterators的API,该API看起来更加简洁

foreach ($files as $file) {
    if (
        in_array($file->getBasename(), $this->excluded_files) ||
        in_array(basename($file->getPath()), $this->excluded_files)
    ) {
        continue;
    }
    $tmpName = str_replace($directory, '', $file->getPathname());

    if ($file->isDir()) {
        $this->zip->addEmptyDir($tmpName);
    } else {
        $this->zip->addFromString($tmpName, file_get_contents($file));
    }
}

请注意,我们正在根据两个条件进行检查:检查当前目录是否在排除的数组中;如果类型为file,则检查父目录是否在排除的数组中。


或者,您也可以使用RegexIterator。

$iterator = new RecursiveDirectoryIterator($directory);

$iterator->setFlags(RecursiveDirectoryIterator::SKIP_DOTS);

$recursiveIterator = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::SELF_FIRST);

$files = new RegexIterator($recursiveIterator, '#^((?!migration|\.git).)*$#');

foreach ($files as $file) {
    $tmpName = str_replace($directory, '', $file->getPathname());

    if ($file->isDir()) {
        $this->zip->addEmptyDir($tmpName);
    } else {
        $this->zip->addFromString($tmpName, file_get_contents($file));
    }
}

return $list;