Znalazłem tutaj w stackoveflow kilka kodów, jak spakować określony plik, ale co z określonym folderem?
Folder/
index.html
picture.jpg
important.txt
w środku My Folder
są pliki. po spakowaniu My Folder
chcę również usunąć całą zawartość folderu z wyjątkiem plików important.txt
.
Znalazłem to tutaj na stosie
Potrzebuję twojej pomocy. dzięki.
Odpowiedzi:
Kod zaktualizowany 2015/04/22.
Spakuj cały folder:
// 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();
Spakuj cały folder + usuń wszystkie pliki z wyjątkiem „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); }
źródło
$zip->close()
nie będzie działać. Sprawdź moją odpowiedź tutajW klasie ZipArchive znajduje się przydatna nieudokumentowana metoda: 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();
Teraz udokumentowane na: www.php.net/manual/en/ziparchive.addglob.php
źródło
addGlob
rekurencyjne?if (!$zipArchive->open($zipFile, ZIPARCHIVE::OVERWRITE))
jest nieprawidłowe i właśnie zabiłem godzinę mojego czasu podczas próby debugowania! Odpowiednio zredagowałem odpowiedź.ZipArchive::OVERWRITE
zakończy się niepowodzeniem, jeśli nazwany plik nie jest obecny, więc użyj(ZipArchive::CREATE | ZipArchive::OVERWRITE)
zamiast tego (zakładając, że chcesz utworzyć lub nadpisać, jeśli ma to zastosowanie).Spróbuj tego:
$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();
Nie będzie to jednak spakować rekursywnie.
źródło
My folder
, ale mam również folder w folderze,My folder
co powoduje błąd: OdmowaMy folder
if (!is_dir($file) && $file != 'target_folder...')
zamiast tego. Lub sprawdź odpowiedź @kread, jeśli chcesz zipować rekurencyjnie, jest to najbardziej efektywny sposób.My folder
nadal nie jest usuwany, ale i tak nie ma więcej błędów.$zip->close()
nie będzie działać. Sprawdź moją odpowiedź tutajZakładam, że to działa na serwerze, na którym aplikacja zip znajduje się w ścieżce wyszukiwania. Powinno być prawdziwe dla wszystkich serwerów opartych na Uniksie i, jak sądzę, większości serwerów opartych na systemie Windows.
exec('zip -r archive.zip "My folder"'); unlink('My\ folder/index.html'); unlink('My\ folder/picture.jpg');
Następnie archiwum będzie znajdować się w pliku archive.zip. Należy pamiętać, że spacje w nazwach plików lub folderów są częstą przyczyną błędów i należy ich unikać, jeśli to możliwe.
źródło
Próbowałem z poniższym kodem i działa. Kod nie wymaga objaśnień, daj mi znać, jeśli masz jakieś pytania.
<?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'; } ?>
źródło
ini_set('memory_limit', '512M');
przed wykonaniem skryptu iini_restore('memory_limit');
na koniec. Należało uniknąć braku pamięci w przypadku ciężkich folderów (był to folder większy niż 500 MB).Jest to funkcja, która spakowuje cały folder i jego zawartość do pliku zip i możesz jej użyć w prosty sposób:
addzip ("path/folder/" , "/path2/folder.zip" );
funkcja:
// 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"; }
źródło
Dlaczego nie Wypróbuj EFS PhP-ZiP MultiVolume Script ... Spakowałem i przeniosłem setki koncertów i miliony plików ... ssh jest potrzebne do efektywnego tworzenia archiwów.
Ale wierzę, że pliki wynikowe mogą być używane z exec bezpośrednio z php:
exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');
Nie wiem, czy to działa. Nie próbowałem ...
„Sekretem” jest to, że czas wykonania archiwizacji nie powinien przekraczać czasu dozwolonego na wykonanie kodu PHP.
źródło
Oto działający przykład tworzenia plików ZIP w 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();
źródło
Znalazłem ten post w Google jako drugi najlepszy wynik, najpierw użyłem exec :(
W każdym razie, chociaż nie odpowiadało to dokładnie moim potrzebom ... Postanowiłem zamieścić odpowiedź dla innych z moją szybką, ale rozszerzoną wersją tego.
CECHY SKRYPTU
W każdym razie, do skryptu ... Chociaż może to wyglądać na dużo ... Pamiętaj, że jest tu nadmiar ... Więc nie krępuj się, aby usunąć sekcje raportowania w razie potrzeby ...
Może również wyglądać niechlujnie, a niektóre rzeczy można łatwo wyczyścić ... Więc nie komentuj tego, to tylko szybki skrypt z podstawowymi komentarzami wrzuconymi ... NIE DO UŻYTKU NA ŻYWO ... Ale łatwe do wyczyszczenia do użytku na żywo !
W tym przykładzie jest uruchamiany z katalogu znajdującego się w głównym folderze www / public_html. Aby dostać się do katalogu głównego, wystarczy podróżować w górę o jeden folder.
<?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]; } ?>
CO TO ROBI??
Po prostu spakuje całą zawartość zmiennej $ pathBase i zapisze zip w tym samym folderze. Wykonuje proste wykrywanie poprzednich kopii zapasowych i pomija je.
BACKUP CRON
Ten skrypt, który właśnie przetestowałem na Linuksie i działał dobrze z pracą cron z użyciem bezwzględnego adresu URL dla pathBase.
źródło
Użyj tej funkcji:
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(); }
Przykładowe zastosowanie:
zip('/folder/to/compress/', './compressed.zip');
źródło
Użyj tego działa dobrze.
$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; }
źródło
Utwórz folder zip w PHP.
Metoda tworzenia 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; } }
Wywołaj metodę zip
$source = $source_directory; $destination = $destination_directory; $zipcreation = $this->zip_creation($source, $destination);
źródło
Zrobiłem małe poprawki w skrypcie.
<?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(); ?>
źródło
To rozwiąże Twój problem. Proszę, spróbuj.
$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();
źródło
Dla każdego, kto czyta ten post i szuka, dlaczego spakować pliki za pomocą addFile zamiast addFromString, który nie spakuje plików z ich bezwzględną ścieżką (po prostu spakuje pliki i nic więcej), zobacz moje pytanie i odpowiedź tutaj
źródło