Я нашел здесь в stackoverflow некоторые коды о том, как ZIP-файл, но как насчет конкретной папки?
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();
// 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();
Теперь задокументировано по адресу: http://www.php.net/manual/en/ziparchive.addglob.php
Попробуй это:
$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 и, я думаю, большинство оконных серверов.
exec('zip -r archive.zip "My folder"'); unlink('My\ folder/index.html'); unlink('My\ folder/picture.jpg');
После этого архив будет находиться в файле archive.zip. Имейте в виду, что пробелы в именах файлов или папок являются общей причиной ошибок и их следует избегать, когда это возможно.
Я попытался с кодом ниже, и он работает. Код сам пояснительный, пожалуйста, дайте мне знать, если у вас есть какие-либо вопросы.
<?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'; } ?>
Это функция, которая застегивает всю папку и ее содержимое в 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"; }
Почему бы не попробовать EFS PhP-ZiP MultiVolume Script … Я закрепил и передал сотни концертов и миллионы файлов … ssh необходим для эффективного создания архивов.
Но я верю, что полученные файлы могут использоваться с exec непосредственно из php:
exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');
Я не знаю, работает ли это. Я не пробовал …
«секрет» заключается в том, что время выполнения архивации не должно превышать время, разрешенное для выполнения кода PHP.
Это рабочий пример создания ZIP-файлов в PHP:
$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();
Для тех, кто читает это сообщение и ищет причину для zip-файлов, используя 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');
Я нашел этот пост в google как второй верхний результат, сначала использовал exec 🙁
Во всяком случае, пока это не соответствовало моим потребностям. Я решил опубликовать ответ для других с моей быстрой, но расширенной версией этого.
ОСОБЕННОСТИ СКРИПТА
В любом случае, на скрипт .. Хотя это может показаться много .. Помните, что здесь есть избыток. Поэтому не стесняйтесь удалять разделы отчетов по мере необходимости …
Также это может выглядеть беспорядочно, и некоторые вещи могут быть легко очищены … Так что не комментируйте это, его просто быстрый скрипт с базовыми комментариями, добавленными .. НЕ ДЛЯ ЖИЗНИ ИСПОЛЬЗОВАНИЯ .. Но легко очистить для живого использования !
В этом примере он запускается из каталога, находящегося внутри корневой папки 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 BACKUP
Этот скрипт, который я только что протестировал на linux, отлично работал с заданием cron с использованием абсолютного URL-адреса для pathBase.