PHP를 사용하여 전체 폴더를 압축하는 방법
stackoveflow에서 특정 파일을 압축하는 방법에 대한 일부 코드를 찾았지만 특정 폴더는 어떻습니까?
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();
이제 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 응용 프로그램이 검색 경로에있는 서버에서 실행되고 있다고 가정합니다. 모든 유닉스 기반에 해당해야하며 대부분의 Windows 기반 서버를 추측합니다.
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가 필요합니다.
그러나 결과 파일을 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();
이 기능을 사용하십시오 :
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
$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();
Google 에서이 게시물을 두 번째 최고 결과로 찾았습니다. 처음에는 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을 저장합니다. 이전 백업을 간단히 감지하여 건너 뜁니다.
크론 백업
이 스크립트는 방금 Linux에서 테스트했으며 pathBase에 절대 URL을 사용하여 cron 작업에서 정상적으로 작동했습니다.
For anyone reading this post and looking for a why to zip the files using addFile instead of addFromString, that does not zip the files with their absolute path (just zips the files and nothing else), see my question and answer here
참고URL : https://stackoverflow.com/questions/4914750/how-to-zip-a-whole-folder-using-php
'IT story' 카테고리의 다른 글
부트 스트랩 툴팁 색상 변경 (0) | 2020.07.28 |
---|---|
setImageDrawable을 동적으로 사용하여 ImageView에서 이미지 설정 (0) | 2020.07.28 |
Linq : Select와 Where의 차이점은 무엇입니까 (0) | 2020.07.27 |
DbArithmeticExpression 인수에는 숫자 공통 유형이 있어야합니다. (0) | 2020.07.27 |
줄 번호가없는 배쉬 히스토리 (0) | 2020.07.27 |