【问题标题】:How to zip a whole folder using PHP如何使用 PHP 压缩整个文件夹
【发布时间】:2011-06-22 08:00:33
【问题描述】:

我在 stackoveflow 找到了一些关于如何压缩特定文件的代码,但是特定文件夹呢?

Folder/
  index.html
  picture.jpg
  important.txt

My Folder里面,有文件。压缩My Folder后,我还想删除除important.txt之外的文件夹的全部内容。

stack 找到这个

我需要你的帮助。 谢谢。

【问题讨论】:

  • 据我所知,您提供的 stackoverflow 链接实际上会压缩多个文件。哪部分有问题?
  • @lasseespeholt 我给你的链接只压缩一个特定的文件,而不是文件夹和文件夹的内容..
  • 他获取一组文件(本质上是一个文件夹)并将所有文件添加到 zip 文件中(循环)。我可以看到现在已经发布了一个很好的答案 +1 :) 这是相同的代码,数组现在只是一个目录中的文件列表。

标签: php zip


【解决方案1】:

如果您有子文件夹,并且想要保留文件夹的结构,请执行以下操作:

$zip = new \ZipArchive();
$fileName = "my-package.zip";
if ($zip->open(public_path($fileName), \ZipArchive::CREATE) === true)
{
    $files = \Illuminate\Support\Facades\File::allFiles(
        public_path('/MY_FOLDER_PATH/')
    );

    foreach ($files as $file) {
        $zip->addFile($file->getPathname(), $file->getRelativePathname());
    }

    $zip->close();
    return response()
        ->download(public_path($fileName))
        ->deleteFileAfterSend(true);
}

deleteFileAfterSend(true) 从服务器中删除文件my-package.zip

不要忘记将/MY_FOLDER_PATH/ 更改为您要下载的文件夹的路径。

【讨论】:

    【解决方案2】:

    包括所有子文件夹:

    new GoodZipArchive('path/to/input/folder',    'path/to/output_zip_file.zip') ;
    

    这里是source-code(可能有更新,但下面我放了那个代码的副本):

    class GoodZipArchive extends ZipArchive 
    {
        public function __construct($a=false, $b=false) { $this->create_func($a, $b);  }
        
        public function create_func($input_folder=false, $output_zip_file=false)
        {
            if($input_folder !== false && $output_zip_file !== false)
            {
                $res = $this->open($output_zip_file, ZipArchive::CREATE);
                if($res === TRUE)   { $this->addDir($input_folder, basename($input_folder)); $this->close(); }
                else                { echo 'Could not create a zip archive. Contact Admin.'; }
            }
        }
        
        // Add a Dir with Files and Subdirs to the archive
        public function addDir($location, $name) {
            $this->addEmptyDir($name);
            $this->addDirDo($location, $name);
        }
    
        // Add Files & Dirs to archive 
        private function addDirDo($location, $name) {
            $name .= '/';         $location .= '/';
            // Read all Files in Dir
            $dir = opendir ($location);
            while ($file = readdir($dir))    {
                if ($file == '.' || $file == '..') continue;
              // Rekursiv, If dir: GoodZipArchive::addDir(), else ::File();
                $do = (filetype( $location . $file) == 'dir') ? 'addDir' : 'addFile';
                $this->$do($location . $file, $name . $file);
            }
        } 
    }
    

    【讨论】:

      【解决方案3】:

      ZipArchive 类中有一个有用的未记录方法:addGlob();

      $zipFile = "./testZip.zip";
      $zipArchive = new ZipArchive();
      
      if ($zipArchive->open($zipFile, (ZipArchive::CREATE | ZipArchive::OVERWRITE)) !== true)
          die("Failed to create archive\n");
      
      $zipArchive->addGlob("./*.txt");
      if ($zipArchive->status != ZIPARCHIVE::ER_OK)
          echo "Failed to write files to zip\n";
      
      $zipArchive->close();
      

      现在记录在:www.php.net/manual/en/ziparchive.addglob.php

      【讨论】:

      • @netcoder - 编写用于测试它的 phpt 的好处......基本上,通读 ZipArchive 类的源代码,并在那里找到它......还有一个未记录的 addPattern()采用正则表达式样式模式的方法,但我从未设法让它工作(可能是类中的错误)
      • @kread - 你可以将它与任何可以使用 glob() 提取的文件列表一起使用,所以我发现它非常有用,因为我发现了它。
      • addGlob 是递归的吗?
      • ZipArchive::open() 在失败时返回一个非零整数,因此检查 if (!$zipArchive->open($zipFile, ZIPARCHIVE::OVERWRITE)) 是无效的,只是浪费了我一个小时的时间来尝试调试!已相应地编辑了答案。
      • 此外,如果指定文件不存在,仅使用 ZipArchive::OVERWRITE 将失败,因此请改用 (ZipArchive::CREATE | ZipArchive::OVERWRITE)(假设您要创建或覆盖适用)。
      【解决方案4】:

      在 PHP 中创建一个 zip 文件夹。

      Zip 创建方法

         public function zip_creation($source, $destination){
          $dir = opendir($source);
          $result = ($dir === false ? false : true);
      
          if ($result !== false) {
      
              
              $rootPath = realpath($source);
               
              // Initialize archive object
              $zip = new ZipArchive();
              $zipfilename = $destination.".zip";
              $zip->open($zipfilename, ZipArchive::CREATE | ZipArchive::OVERWRITE );
               
              // Create recursive directory iterator
              /** @var SplFileInfo[] $files */
              $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($rootPath), RecursiveIteratorIterator::LEAVES_ONLY);
               
              foreach ($files as $name => $file)
              {
                  // Skip directories (they would be added automatically)
                  if (!$file->isDir())
                  {
                      // Get real and relative path for current file
                      $filePath = $file->getRealPath();
                      $relativePath = substr($filePath, strlen($rootPath) + 1);
               
                      // Add current file to archive
                      $zip->addFile($filePath, $relativePath);
                  }
              }
               
              // Zip archive will be created only after closing object
              $zip->close();
              
              return TRUE;
          } else {
              return FALSE;
          }
      
      
      }
      

      调用zip方法

      $source = $source_directory;
      $destination = $destination_directory;
      $zipcreation = $this->zip_creation($source, $destination);
      

      【讨论】:

        【解决方案5】:

        使用它工作正常。

        $dir = '/Folder/';
        $zip = new ZipArchive();
        $res = $zip->open(trim($dir, "/") . '.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
        if ($res === TRUE) {
            foreach (glob($dir . '*') as $file) {
                $zip->addFile($file, basename($file));
            }
            $zip->close();
        } else {
            echo 'Failed to create to zip. Error: ' . $res;
        }
        

        【讨论】:

          【解决方案6】:

          使用此功能:

          function zip($source, $destination)
          {
              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 (is_dir($source) === true) {
                  $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
          
                  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 . '/'));
                      } elseif (is_file($file) === true) {
                          $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
                      }
                  }
              } elseif (is_file($source) === true) {
                  $zip->addFromString(basename($source), file_get_contents($source));
              }
          
              return $zip->close();
          }
          

          使用示例:

          zip('/folder/to/compress/', './compressed.zip');
          

          【讨论】:

            【解决方案7】:

            代码更新于 2015 年 4 月 22 日。

            压缩整个文件夹:

            // Get real path for our folder
            $rootPath = realpath('folder-to-zip');
            
            // Initialize archive object
            $zip = new ZipArchive();
            $zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
            
            // Create recursive directory iterator
            /** @var SplFileInfo[] $files */
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($rootPath),
                RecursiveIteratorIterator::LEAVES_ONLY
            );
            
            foreach ($files as $name => $file)
            {
                // Skip directories (they would be added automatically)
                if (!$file->isDir())
                {
                    // Get real and relative path for current file
                    $filePath = $file->getRealPath();
                    $relativePath = substr($filePath, strlen($rootPath) + 1);
            
                    // Add current file to archive
                    $zip->addFile($filePath, $relativePath);
                }
            }
            
            // Zip archive will be created only after closing object
            $zip->close();
            

            压缩整个文件夹 + 删除除“important.txt”以外的所有文件:

            // Get real path for our folder
            $rootPath = realpath('folder-to-zip');
            
            // Initialize archive object
            $zip = new ZipArchive();
            $zip->open('file.zip', ZipArchive::CREATE | ZipArchive::OVERWRITE);
            
            // Initialize empty "delete list"
            $filesToDelete = array();
            
            // Create recursive directory iterator
            /** @var SplFileInfo[] $files */
            $files = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($rootPath),
                RecursiveIteratorIterator::LEAVES_ONLY
            );
            
            foreach ($files as $name => $file)
            {
                // Skip directories (they would be added automatically)
                if (!$file->isDir())
                {
                    // Get real and relative path for current file
                    $filePath = $file->getRealPath();
                    $relativePath = substr($filePath, strlen($rootPath) + 1);
            
                    // Add current file to archive
                    $zip->addFile($filePath, $relativePath);
            
                    // Add current file to "delete list"
                    // delete it later cause ZipArchive create archive only after calling close function and ZipArchive lock files until archive created)
                    if ($file->getFilename() != 'important.txt')
                    {
                        $filesToDelete[] = $filePath;
                    }
                }
            }
            
            // Zip archive will be created only after closing object
            $zip->close();
            
            // Delete all files from "delete list"
            foreach ($filesToDelete as $file)
            {
                unlink($file);
            }
            

            【讨论】:

            • 您必须将 dir(此脚本所在的位置)上的 chmod(可写)设置为 777。例如:如果脚本位于 /var/www/localhost/script.php,那么您需要设置 chmod 0777在目录 /var/www/localhost/.
            • 在调用$zip->close() 之前删除文件将不起作用。检查我的答案here
            • @alnassre 这是问题的要求:“我还想删除文件夹的全部内容,除了important.txt”。另外我建议您在执行代码之前始终阅读代码。
            • @alnassre 哈哈哈 ...对不起 :) ...哈哈哈
            • @nick-newman,是的,要计算百分比,您可以在循环内使用 php.net/manual/ru/function.iterator-count.php + counter。关于压缩级别 - 目前无法使用 ZipArchive:stackoverflow.com/questions/1833168/…
            【解决方案8】:

            对于阅读这篇文章并寻找为什么使用 addFile 而不是 addFromString 压缩文件的任何人,它不会使用它们的绝对路径压缩文件(只是压缩文件而不是其他任何东西),请参阅我的问题和回答 @987654321 @

            【讨论】:

              【解决方案9】:

              我在 google 中发现这篇文章是第二个最佳结果,首先是使用 exec :(

              无论如何,虽然这并不完全符合我的需求。我决定用我的快速但扩展的版本为其他人发布答案。

              脚本功能

              • 备份文件按天命名,PREFIX-YYYY-MM-DD-POSTFIX.EXTENSION
              • 文件报告/丢失
              • 以前的备份列表
              • 不压缩/包括以前的备份;)
              • 适用于 windows/linux

              无论如何,在脚本上。虽然它可能看起来很多..记住这里有多余的..所以随意删除报告部分根据需要...

              它也可能看起来很乱,并且某些东西可以很容易地清理......所以不要评论它,它只是一个包含基本 cmets 的快速脚本.. 不适合现场使用.. 但易于清理现场使用!

              在本例中,它是从位于根 www / public_html 文件夹内的目录运行的。因此只需向上移动一个文件夹即可到达根目录。

              <?php
                  // DIRECTORY WE WANT TO BACKUP
                  $pathBase = '../';  // Relate Path
              
                  // ZIP FILE NAMING ... This currently is equal to = sitename_www_YYYY_MM_DD_backup.zip 
                  $zipPREFIX = "sitename_www";
                  $zipDATING = '_' . date('Y_m_d') . '_';
                  $zipPOSTFIX = "backup";
                  $zipEXTENSION = ".zip";
              
                  // SHOW PHP ERRORS... REMOVE/CHANGE FOR LIVE USE
                  ini_set('display_errors',1);
                  ini_set('display_startup_errors',1);
                  error_reporting(-1);
              
              
              
              
              // ############################################################################################################################
              //                                  NO CHANGES NEEDED FROM THIS POINT
              // ############################################################################################################################
              
                  // SOME BASE VARIABLES WE MIGHT NEED
                  $iBaseLen = strlen($pathBase);
                  $iPreLen = strlen($zipPREFIX);
                  $iPostLen = strlen($zipPOSTFIX);
                  $sFileZip = $pathBase . $zipPREFIX . $zipDATING . $zipPOSTFIX . $zipEXTENSION;
                  $oFiles = array();
                  $oFiles_Error = array();
                  $oFiles_Previous = array();
              
                  // SIMPLE HEADER ;)
                  echo '<center><h2>PHP Example: ZipArchive - Mayhem</h2></center>';
              
                  // CHECK IF BACKUP ALREADY DONE
                  if (file_exists($sFileZip)) {
                      // IF BACKUP EXISTS... SHOW MESSAGE AND THATS IT
                      echo "<h3 style='margin-bottom:0px;'>Backup Already Exists</h3><div style='width:800px; border:1px solid #000;'>";
                          echo '<b>File Name: </b>',$sFileZip,'<br />';
                          echo '<b>File Size: </b>',$sFileZip,'<br />';
                      echo "</div>";
                      exit; // No point loading our function below ;)
                  } else {
              
                      // NO BACKUP FOR TODAY.. SO START IT AND SHOW SCRIPT SETTINGS
                      echo "<h3 style='margin-bottom:0px;'>Script Settings</h3><div style='width:800px; border:1px solid #000;'>";
                          echo '<b>Backup Directory: </b>',$pathBase,'<br /> ';
                          echo '<b>Backup Save File: </b>',$sFileZip,'<br />';
                      echo "</div>";
              
                      // CREATE ZIPPER AND LOOP DIRECTORY FOR SUB STUFF
                      $oZip = new ZipArchive;
                      $oZip->open($sFileZip,  ZipArchive::CREATE | ZipArchive::OVERWRITE);
                      $oFilesWrk = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($pathBase),RecursiveIteratorIterator::LEAVES_ONLY);
                      foreach ($oFilesWrk as $oKey => $eFileWrk) {
                          // VARIOUS NAMING FORMATS OF THE CURRENT FILE / DIRECTORY.. RELATE & ABSOLUTE
                          $sFilePath = substr($eFileWrk->getPathname(),$iBaseLen, strlen($eFileWrk->getPathname())- $iBaseLen);
                          $sFileReal = $eFileWrk->getRealPath();
                          $sFile = $eFileWrk->getBasename();
              
                          // WINDOWS CORRECT SLASHES
                          $sMyFP = str_replace('\\', '/', $sFileReal);
              
                          if (file_exists($sMyFP)) {  // CHECK IF THE FILE WE ARE LOOPING EXISTS
                              if ($sFile!="."  && $sFile!="..") { // MAKE SURE NOT DIRECTORY / . || ..
                                  // CHECK IF FILE HAS BACKUP NAME PREFIX/POSTFIX... If So, Dont Add It,, List It
                                  if (substr($sFile,0, $iPreLen)!=$zipPREFIX && substr($sFile,-1, $iPostLen + 4)!= $zipPOSTFIX.$zipEXTENSION) {
                                      $oFiles[] = $sMyFP;                     // LIST FILE AS DONE
                                      $oZip->addFile($sMyFP, $sFilePath);     // APPEND TO THE ZIP FILE
                                  } else {
                                      $oFiles_Previous[] = $sMyFP;            // LIST PREVIOUS BACKUP
                                  }
                              }
                          } else {
                              $oFiles_Error[] = $sMyFP;                       // LIST FILE THAT DOES NOT EXIST
                          }
                      }
                      $sZipStatus = $oZip->getStatusString();                 // GET ZIP STATUS
                      $oZip->close(); // WARNING: Close Required to append files, dont delete any files before this.
              
                      // SHOW BACKUP STATUS / FILE INFO
                      echo "<h3 style='margin-bottom:0px;'>Backup Stats</h3><div style='width:800px; height:120px; border:1px solid #000;'>";
                          echo "<b>Zipper Status: </b>" . $sZipStatus . "<br />";
                          echo "<b>Finished Zip Script: </b>",$sFileZip,"<br />";
                          echo "<b>Zip Size: </b>",human_filesize($sFileZip),"<br />";
                      echo "</div>";
              
              
                      // SHOW ANY PREVIOUS BACKUP FILES
                      echo "<h3 style='margin-bottom:0px;'>Previous Backups Count(" . count($oFiles_Previous) . ")</h3><div style='overflow:auto; width:800px; height:120px; border:1px solid #000;'>";
                      foreach ($oFiles_Previous as $eFile) {
                          echo basename($eFile) . ", Size: " . human_filesize($eFile) . "<br />";
                      }
                      echo "</div>";
              
                      // SHOW ANY FILES THAT DID NOT EXIST??
                      if (count($oFiles_Error)>0) {
                          echo "<h3 style='margin-bottom:0px;'>Error Files, Count(" . count($oFiles_Error) . ")</h3><div style='overflow:auto; width:800px; height:120px; border:1px solid #000;'>";
                          foreach ($oFiles_Error as $eFile) {
                              echo $eFile . "<br />";
                          }
                          echo "</div>";
                      }
              
                      // SHOW ANY FILES THAT HAVE BEEN ADDED TO THE ZIP
                      echo "<h3 style='margin-bottom:0px;'>Added Files, Count(" . count($oFiles) . ")</h3><div style='overflow:auto; width:800px; height:120px; border:1px solid #000;'>";
                      foreach ($oFiles as $eFile) {
                          echo $eFile . "<br />";
                      }
                      echo "</div>";
              
                  }
              
              
                  // CONVERT FILENAME INTO A FILESIZE AS Bytes/Kilobytes/Megabytes,Giga,Tera,Peta
                  function human_filesize($sFile, $decimals = 2) {
                      $bytes = filesize($sFile);
                      $sz = 'BKMGTP';
                      $factor = floor((strlen($bytes) - 1) / 3);
                      return sprintf("%.{$decimals}f", $bytes / pow(1024, $factor)) . @$sz[$factor];
                  }
              ?>
              

              它有什么作用??

              它会简单地压缩变量 $pathBase 的完整内容并将压缩文件存储在同一个文件夹中。它对以前的备份进行简单检测并跳过它们。

              CRON 备份

              我刚刚在 linux 上测试过这个脚本,并且在使用绝对 url 作为 pathBase 的 cron 作业中运行良好。

              【讨论】:

              • 我也排除了删除脚本,你可以看到这个接受的答案
              • 必须喜欢那些随机的反对票,而无需评论解释原因。
              【解决方案10】:

              这将解决您的问题。请尝试一下。

              $zip = new ZipArchive;
              $zip->open('testPDFZip.zip', ZipArchive::CREATE);
              foreach (glob(APPLICATION_PATH."pages/recruitment/uploads/test_pdf_folder/*") as $file) {
                  $new_filename = end(explode("/",$file));
                  $zip->addFile($file,"emp/".$new_filename);
              }           
              $zip->close();
              

              【讨论】:

                【解决方案11】:

                我尝试使用下面的代码,它正在工作。该代码是不言自明的,如果您有任何问题,请告诉我。

                <?php
                class FlxZipArchive extends ZipArchive 
                {
                 public function addDir($location, $name) 
                 {
                       $this->addEmptyDir($name);
                       $this->addDirDo($location, $name);
                 } 
                 private function addDirDo($location, $name) 
                 {
                    $name .= '/';
                    $location .= '/';
                    $dir = opendir ($location);
                    while ($file = readdir($dir))
                    {
                        if ($file == '.' || $file == '..') continue;
                        $do = (filetype( $location . $file) == 'dir') ? 'addDir' : 'addFile';
                        $this->$do($location . $file, $name . $file);
                    }
                 } 
                }
                ?>
                
                <?php
                $the_folder = '/path/to/folder/to/be/zipped';
                $zip_file_name = '/path/to/zip/archive.zip';
                $za = new FlxZipArchive;
                $res = $za->open($zip_file_name, ZipArchive::CREATE);
                if($res === TRUE) 
                {
                    $za->addDir($the_folder, basename($the_folder));
                    $za->close();
                }
                else{
                echo 'Could not create a zip archive';
                }
                ?>
                

                【讨论】:

                • 优秀的解决方案。它也适用于 laravel 5.5。真的很喜欢。 (y)
                • 很棒的代码!干净,简单,完美的工作! ;) 这对我来说似乎是最好的答复。如果它可以帮助某人:我只是在执行脚本之前添加了ini_set('memory_limit', '512M');,最后添加了ini_restore('memory_limit');。有必要避免在文件夹很重的情况下内存不足(这是一个大于 500MB 的文件夹)。
                • 在我的环境(PHP 7.3,Debian)中创建了一个没有目录列表的 ZIP 存档(大的空文件)。我不得不更改以下行: $name .= '/';进入 $name = ($name == '.' ? '' : $name .'/');
                • 这对我有用。感谢分享。干杯!
                【解决方案12】:

                我对脚本做了一些小的改进。

                  <?php
                    $directory = "./";
                    //create zip object
                    $zip = new ZipArchive();
                    $zip_name = time().".zip";
                    $zip->open($zip_name,  ZipArchive::CREATE);
                    $files = new RecursiveIteratorIterator(
                        new RecursiveDirectoryIterator($directory),
                        RecursiveIteratorIterator::LEAVES_ONLY
                    );
                    foreach ($files as $file) {
                        $path = $file->getRealPath();
                        //check file permission
                        if(fileperms($path)!="16895"){
                            $zip->addFromString(basename($path),  file_get_contents($path)) ;
                            echo "<span style='color:green;'>{$path} is added to zip file.<br /></span> " ;
                        }
                        else{
                            echo"<span style='color:red;'>{$path} location could not be added to zip<br /></span>";
                        }
                    }
                    $zip->close();
                    ?>
                

                【讨论】:

                • 这会压缩文件但目录列表消失了它不再有目录
                【解决方案13】:

                这是一个将整个文件夹及其内容压缩到一个 zip 文件中的功能,您可以像这样简单地使用它:

                addzip ("path/folder/" , "/path2/folder.zip" );
                

                功能:

                // compress all files in the source directory to destination directory 
                    function create_zip($files = array(), $dest = '', $overwrite = false) {
                    if (file_exists($dest) && !$overwrite) {
                        return false;
                    }
                    if (($files)) {
                        $zip = new ZipArchive();
                        if ($zip->open($dest, $overwrite ? ZIPARCHIVE::OVERWRITE : ZIPARCHIVE::CREATE) !== true) {
                            return false;
                        }
                        foreach ($files as $file) {
                            $zip->addFile($file, $file);
                        }
                        $zip->close();
                        return file_exists($dest);
                    } else {
                        return false;
                    }
                }
                
                function addzip($source, $destination) {
                    $files_to_zip = glob($source . '/*');
                    create_zip($files_to_zip, $destination);
                    echo "done";
                }
                

                【讨论】:

                • 如何使用此脚本自动在备份中包含子文件夹? @Alireza
                【解决方案14】:

                这是一个用 PHP 制作 ZIP 的工作示例:

                $zip = new ZipArchive();
                $zip_name = time().".zip"; // Zip name
                $zip->open($zip_name,  ZipArchive::CREATE);
                foreach ($files as $file) {
                  echo $path = "uploadpdf/".$file;
                  if(file_exists($path)){
                  $zip->addFromString(basename($path),  file_get_contents($path));---This is main function  
                  }
                  else{
                   echo"file does not exist";
                  }
                }
                $zip->close();
                

                【讨论】:

                  【解决方案15】:

                  为什么不试试 EFS PhP-ZiP MultiVolume Script...我压缩并传输了数百个演出和数百万个文件...需要 ssh 才能有效地创建档案。

                  但我相信生成的文件可以直接从 php 与 exec 一起使用:

                  exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');
                  

                  我不知道它是否有效。我没试过……

                  “秘诀”是归档的执行时间不能超过PHP代码的执行时间。

                  【讨论】:

                    【解决方案16】:

                    我假设这是在 zip 应用程序位于搜索路径中的服务器上运行的。应该适用于所有基于 unix 的服务器,我猜大多数基于 Windows 的服务器。

                    exec('zip -r archive.zip "My folder"');
                    unlink('My\ folder/index.html');
                    unlink('My\ folder/picture.jpg');
                    

                    之后存档将驻留在 archive.zip 中。请记住,文件或文件夹名称中的空白是导致错误的常见原因,应尽可能避免。

                    【讨论】:

                      【解决方案17】:

                      试试这个:

                      $zip = new ZipArchive;
                      $zip->open('myzip.zip', ZipArchive::CREATE);
                      foreach (glob("target_folder/*") as $file) {
                          $zip->addFile($file);
                          if ($file != 'target_folder/important.txt') unlink($file);
                      }
                      $zip->close();
                      

                      这个不会递归压缩。

                      【讨论】:

                      • 它确实删除了My folder 中的一些文件,但我在My folder 文件夹中还有一个文件夹,这给了我一个错误:通过取消与My folder 中的文件夹的链接而拒绝权限
                      • @Stupefy:改用if (!is_dir($file) &amp;&amp; $file != 'target_folder...')。或者如果您想递归压缩,请查看@kread answer,这是最有效的方式。
                      • My folder中的文件夹仍然没有被删除,但无论如何也没有更多错误。
                      • 我也忘了提到我没有创建 .zip 文件。
                      • 在调用$zip-&gt;close() 之前删除文件将不起作用。检查我的答案here
                      猜你喜欢
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 1970-01-01
                      • 2019-09-19
                      • 2013-12-25
                      相关资源
                      最近更新 更多