如何使用PHP压缩整个文件夹
我在这里找到了一些关于如何压缩特定文件的代码,但是特定的文件夹怎么样?
Folder/ index.html picture.jpg important.txt
在My Folder
里面,有文件。 在压缩My Folder
,我也想删除文件夹中除important.txt
以外的全部内容。
在这里找到这个堆栈
我需要你的帮助。 谢谢。
代码更新2015/04/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); }
在ZipArchive类中有一个有用的未记录的方法:addGlob();
$zipFile = "./testZip.zip"; $zipArchive = new ZipArchive(); if (!$zipArchive->open($zipFile, ZIPARCHIVE::OVERWRITE)) 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();
尝试这个:
$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中。 请记住,文件或文件夹名称中的空白是导致错误的常见原因,应尽可能避免。
这是一个将整个文件夹及其内容压缩到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 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'; } ?>
为什么不试试EFS PhP-ZiP MultiVolume脚本 …我压缩并传输了数百个演出和数百万个文件… 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();
我在剧本中做了一些小的改进。
<?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();
任何人阅读这篇文章,并寻找为什么使用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');
我发现这个职位在谷歌作为第二个最重要的结果,首先是使用exec 🙁
无论如何,虽然这并没有完全满足我的需求..我决定发表一个答案,为我的快速,但扩展版本的这个。
脚本功能
- 备份文件的命名一天一天,PREFIX-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]; } ?>
它有什么作用??
它将简单地压缩变量$ pathBase的完整内容,并将zip存储在同一个文件夹中。 它为以前的备份做了一个简单的检测并跳过它们。
CRON备份
这个脚本我刚才在linux上测试过,在cron作业中使用绝对路径作为pathBase。