如何使用PHP压缩整个文件夹

如何使用PHP压缩整个文件夹,php,zip,Php,Zip,我在stackoveflow找到了一些关于如何压缩特定文件的代码,但是如何压缩特定文件夹呢 Folder/ index.html picture.jpg important.txt 在我的文件夹中,有一些文件。压缩我的文件夹后,我还想删除文件夹中除important.txt之外的所有内容 在这里找到这个 我需要你的帮助。 谢谢。试试这个: $zip = new ZipArchive; $zip->open('myzip.zip', ZipArchive::CREATE); f

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

Folder/
  index.html
  picture.jpg
  important.txt
我的文件夹中
,有一些文件。压缩
我的文件夹
后,我还想删除文件夹中除
important.txt
之外的所有内容

在这里找到这个

我需要你的帮助。 谢谢。

试试这个:

$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();

但是,这个不会递归压缩。

我假设它运行在一个服务器上,而zip应用程序位于搜索路径中。对于所有基于unix的服务器,我想大多数基于windows的服务器都应该是这样

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

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

代码于2015年4月22日更新

压缩整个文件夹: 压缩整个文件夹+删除除“important.txt”以外的所有文件:
ZipArchive类中有一个有用的未记录方法:addGlob()


现在记录在:

为什么不试试EFS PhP ZiP多卷脚本呢。。。我压缩并传输了数百份文件和数百万份文件。。。ssh是有效创建归档所必需的

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

exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');
我不知道它是否有效。我没有试过


“秘诀”是存档的执行时间不应超过允许执行PHP代码的时间。

这是在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();

这是一个将整个文件夹及其内容压缩到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";
}

我对剧本做了一些小改进

  <?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();
    ?>

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

$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();

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

<?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';
}
?>

我在谷歌找到了这篇文章,作为第二个排名靠前的结果,第一个是使用exec:(

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

脚本功能

  • 每天备份文件命名,前缀为-YYYY-MM-DD-POSTFIX.EXTENSION
  • 文件报告/丢失
  • 以前的备份列表
  • 不压缩/包括以前的备份;)
  • 在windows/linux上工作
不管怎样,在剧本上。。虽然看起来可能很多。。记住这里有多余的东西。。因此,请根据需要随时删除报告部分

而且它看起来也很凌乱,某些东西可以很容易地清理干净。。。所以不要评论它,它只是一个包含基本评论的快速脚本。。不供现场使用。。但便于现场清理使用

在本例中,它从根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];
    }
?>

对于阅读本文并查找使用addFile而不是addFromString压缩文件的原因的任何人,如果他们不使用文件的绝对路径压缩文件(只压缩文件,其他什么都不压缩),请参阅我的问题和答案使用此功能:

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');

使用这个很好

$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;
}

在PHP中创建一个zip文件夹

Zip创建方法 调用zip方法
包括所有子文件夹:

new GoodZipArchive('path/to/input/folder',    'path/to/output_zip_file.zip') ;
下面是(可能有一个更新,但下面我放了该代码的副本):


据我所知,您提供的stackoverflow链接实际上可以压缩多个文件。你对哪一部分有问题?@lassespeholt我给你的链接只压缩一个特定的文件,而不是文件夹和文件夹的内容。他获取一个文件数组(本质上是一个文件夹),并将所有文件添加到zip文件(循环)。我可以看到一个很好的答案现在已经发布+1:)这是相同的代码,数组现在只是一个目录中的文件列表。可能的重复可以帮助您确定它确实删除了
我的文件夹中的一些文件
,但是我的文件夹
My folder
中也有一个文件夹,这给了我一个错误:通过将文件夹与
My folder中的
@Stupefy解除链接拒绝权限:尝试
如果(!is_dir($file)&&&$file!='target_folder…')
。或者检查是否要递归压缩,这是最有效的方法。
我的文件夹
中的文件夹仍然没有被删除,但仍然没有其他错误。我还忘了提到没有创建.zip文件。在调用
$zip->close()
之前删除这些文件将不起作用。检查我的答案@netcoder-编写phpt测试它的好处。。。基本上,通读ZipArchive类的源代码,并在那里找到它。。。。还有一个未记录的addPattern()方法,它采用了regexp样式的模式,但我从来没有设法让它工作过(可能是类中的一个bug)@kread-您可以将它用于任何可以使用glob()提取的文件列表,因此我发现它非常有用。是不是
addGlob
递归?ZipArchive::open()失败时返回一个非零整数,因此检查
是否(!$zipArchive->open($zipFile,zipArchive::OVERWRITE))
无效,并在尝试调试时占用了我一小时的时间!已相应地编辑了答案。此外,如果命名文件不存在,则仅使用
ZipArchive::OVERWRITE
将失败,因此请改用
(ZipArchive::CREATE | ZipArchive::OVERWRITE)
(假设您希望创建或覆盖,视情况而定)。必须将dir(此脚本所在位置)上的chmod(可写)设置为777。例如:如果脚本位于/var/www/localhost/script.php中,则需要在dir/var/www/localhost/上设置chmod 0777。在调用
$zip->close()
之前删除文件将无效。检查我的答案@alnassre,这是问题中的要求:“我还想删除文件夹的全部内容,除了
zip('/folder/to/compress/', './compressed.zip');
$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;
}
   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;
    }


}
$source = $source_directory;
$destination = $destination_directory;
$zipcreation = $this->zip_creation($source, $destination);
new GoodZipArchive('path/to/input/folder',    'path/to/output_zip_file.zip') ;
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);
        }
    } 
}