【问题标题】:zip main folder with sub folder insidezip 主文件夹,里面有子文件夹
【发布时间】:2013-07-09 05:20:40
【问题描述】:

我有一个文件夹,里面有一些文件和子文件夹。我将如何读取目录并压缩主文件夹?

例如:

maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6

我正在使用这个脚本:

function Zip($source, $destination, $include_dir = false)
{

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
        return false;
    }
    $source = str_replace('\\', '/', realpath($source));

    if (is_dir($source) === true)
    {

        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_CHILD);

        if ($include_dir) {

            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= '/' . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // Ignore "." and ".." folders
            if( in_array(substr($file, strrpos($file, '/')+1), array('.', '..')) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

我这样调用函数:

Zip('image/data/','aaa.zip',false);

但我得到的是它压缩了整个C: 文件夹。我想要的只是将文档压缩到image/data/ 文件夹中。

如何格式化正确的目录及其子目录?

【问题讨论】:

    标签: php recursion directory zipfile


    【解决方案1】:

    试试这个。

    zipFile('image/data/','aaa.zip', true);
    
    /**
     * function zipFile.  Creates a zip file from source to destination
     *
     * @param  string $source Source path for zip
     * @param  string $destination Destination path for zip
     * @param  string|boolean $flag OPTIONAL If true includes the folder also
     * @return boolean
     */
    function zipFile($source, $destination, $flag = '')
    {
        if (!extension_loaded('zip') || !file_exists($source)) {
            return false;
        }
    
        $zip = new ZipArchive();
        if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
            return false;
        }
    
        $source = str_replace('\\', '/', realpath($source));
        if($flag)
        {
            $flag = basename($source) . '/';
            //$zip->addEmptyDir(basename($source) . '/');
        }
    
        if (is_dir($source) === true)
        {
            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
            foreach ($files as $file)
            {
                $file = str_replace('\\', '/', realpath($file));
    
                if (is_dir($file) === true)
                {
                    $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
                }
                else if (is_file($file) === true)
                {
                    $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
                }
            }
        }
        else if (is_file($source) === true)
        {
            $zip->addFromString($flag.basename($source), file_get_contents($source));
        }
    
        return $zip->close();
    }
    

    【讨论】:

    • 你能解释为什么$flag吗?我正在使用完整路径并且有一个小故障(第一个目录是空的并显示完整的原始路径)。
    • @brasofilo $flag 这里包括基本目录,所以这里它会将'image/data/' 的所有文件和文件夹压缩到data 目录中
    【解决方案2】:

    我编辑了上面的代码,因为我无法添加空文件夹并避免 C: 驱动器

    $otpt = "C:/xampp/htdocs/restricted/abc.zip";   
    $inpt = "C:/xampp/htdocs/Test/";
    
    
    zipFile($inpt,$otpt, true); //Call to function
    
    function zipFile($source, $destination, $flag = '')
    {
        if (!extension_loaded('zip') || !file_exists($source)) {
           return false;
        }
    
        $zip = new ZipArchive();
        if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
           return false;
        }
    
        $source = str_replace('\\', '/', realpath($source));
        if($flag)
        {
            $flag = basename($source) . '/';
        }
    
        if (is_dir($source) === true)
        {
            $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
    
            foreach ($files as $file)
            {
    
                $file = str_replace('\\', '/', realpath($file));
    
                if (strpos($flag.$file,$source) !== false) { // this will add only the folder we want to add in zip
    
                    if (is_dir($file) === true)
                    {
                        $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
    
                    }
                    else if (is_file($file) === true)
                    {
                        $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
                    }
                }
            }
        }
        else if (is_file($source) === true)
        {
            $zip->addFromString($flag.basename($source), file_get_contents($source));
        }
    
        return $zip->close();
    }
    

    【讨论】:

      【解决方案3】:

      谢谢大家...我发现问题了...

      if (is_dir($source) === true)
      {
          $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
          foreach ($files as $file)
          {
              $file = str_replace('\\', '/', realpath($file));
      
              if (is_dir($file) === true)
              {
                  //$zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/')); //this should be commented so it wont include the main path
              }
              else if (is_file($file) === true)
              {
                  $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
              }
          }
      }
      

      【讨论】:

        【解决方案4】:
               1- You should put all these code in a function  
              function readfile($source){
                  if (is_dir($source) === true) {                      
                   $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
                         foreach ($files as $file)
                    {
                $file = str_replace('\\', '/', realpath($file));
        
                if (is_dir($file) === true)
                {
                    $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
                }
                else if (is_file($file) === true)
                {
                    $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
                }
            }
        }
        else if (is_file($source) === true)
        {
            $zip->addFromString($flag.basename($source), file_get_contents($source));
        }
           // here you would use recursive function
          else if (is_dir($source) === true)
         {
            readfile($source);
        }
        }
        

        总结: 如果你找到一个文件,那么你会做你想要的操作,如果你找到一个目录,你会使用递归函数来遍历目录。

        【讨论】:

          【解决方案5】:

          你应该添加:

          if(basename($file) === '.' || basename($file) === '..'){
            continue;
          }
          

          像这样:

          if (is_dir($source) === true) {
              $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
              foreach ($files as $file) {
                  if(basename($file) === '.' || basename($file) === '..'){
                      continue;
                  }
                  $file = str_replace('\\', '/', realpath($file));
                  if (is_dir($file) === true) {
                      $zip->addEmptyDir(str_replace($source . '/', '', $flag.$file . '/'));
                  } else if (is_file($file) === true) {
                      $zip->addFromString(str_replace($source . '/', '', $flag.$file), file_get_contents($file));
                  }
              }
          } else if (is_file($source) === true) {
              $zip->addFromString($flag.basename($source), file_get_contents($source));
          }
          

          【讨论】:

            【解决方案6】:

            如果你使用 addfile 方法而不是 addfromstring 会更简单

            为了胜利

            public function ArchiveFile($path)
                {
            
                    $path=realpath($path);
            
                    $zip = new \ZipArchive();
                    $path= str_replace('/','\\', $path );
            
                    $nameFile = $path.'\\'.'letter'.time().'.zip';
            
                    if ($zip->open($nameFile,\ZipArchive::CREATE)===TRUE){      
            
            
            
            
                    if (is_dir($path))
                    {
                        $pathSource= $path. '\\';
                    $directory = new \RecursiveDirectoryIterator($path);
                    $files = new \RecursiveIteratorIterator($directory,  \RecursiveIteratorIterator::SELF_FIRST );
                    }
            
            
            
            
                    foreach ($files as $name=>$file)
                    {
            
            
                        if (in_array(substr($name, strrpos($name,'\\')+1), array('.','..')))
                        {
                            continue;
                        }
            
                     if     (is_file($name)===TRUE) {
            
                        $zip->addFile($name, str_replace($pathSource, "", $name));
                         }
            
                    }
            
            
                        $zip->close();
            
            
                    rename($nameFile, $nameFile.'.xlsx');
            

            【讨论】:

            • 您能否在答案中添加一个简短的 OP 示例?
            猜你喜欢
            • 1970-01-01
            • 2015-04-05
            • 1970-01-01
            • 1970-01-01
            • 2013-07-10
            • 2013-10-14
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多