programing

PHP를 사용하여 전체 폴더를 압축하는 방법

projobs 2022. 10. 11. 22:30
반응형

PHP를 사용하여 전체 폴더를 압축하는 방법

여기 stackoveflow에서 특정 파일을 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();

폴더 전체를 압축하고 "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::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();

현재 문서화는 www.php.net/manual/en/ziparchive.addglob.php에서 입수 가능합니다.

이것은 검색 경로에 있는 zip 애플리케이션이 있는 서버에서 실행되고 있을 것입니다.모든 Unix 기반 서버 및 대부분의 Windows 기반 서버에 해당됩니다.

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

이후 아카이브는 archive.zip에 저장됩니다.파일 또는 폴더 이름의 공백은 오류의 일반적인 원인이므로 가능한 한 피해야 합니다.

이것을 시험해 보세요.

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

, 이것은 재귀적으로 압축되지 않습니다.

아래 코드로 시도해보니 동작하고 있습니다.코드는 자체 설명이므로, 문의사항이 있으시면 연락주시기 바랍니다.

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

다음 기능을 사용합니다.

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

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

이것으로 문제가 해결됩니다.한번 써 보세요.

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

두 번째 상위 결과로서 구글에서 이 게시물을 발견했습니다.첫 번째는 exec: ()를 사용한 것입니다.

어쨌든, 이게 제 욕구를 충족시키진 못했지만..저는 저의 빠른 확장 버전으로 다른 분들을 위해 답변을 올리기로 했습니다.

스크립트 기능

  • 백업 파일의 이름을 매일 PREFIX-YYY-MM-DD-POSTFIX로 지정합니다.확장
  • 파일 보고 / 누락
  • 이전 백업 목록
  • 이전 백업은 zip화/포함되지 않습니다.)
  • 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의 전체 내용을 압축하여 동일한 폴더에 저장합니다.이전 백업을 단순하게 탐지하고 건너뜁니다.

크론백업.

방금 Linux에서 테스트한 이 스크립트는 pathBase의 절대 URL을 사용하여 cron 작업에서 정상적으로 동작합니다.

이거 잘 작동하는데 써.

$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 생성 방법

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


}

zip 메서드를 호출합니다.

$source = $source_directory;
$destination = $destination_directory;
$zipcreation = $this->zip_creation($source, $destination);

하위 폴더가 있고 폴더 구조를 유지하려면 다음 작업을 수행합니다.

$zip = new \ZipArchive();
$fileName = "my-package.zip";
if ($zip->open(public_path($fileName), \ZipArchive::CREATE) === true)
{
    $files = \Illuminate\Support\Facades\File::allFiles(
        public_path('/MY_FOLDER_PATH/')
    );

    foreach ($files as $file) {
        $zip->addFile($file->getPathname(), $file->getRelativePathname());
    }

    $zip->close();
    return response()
        ->download(public_path($fileName))
        ->deleteFileAfterSend(true);
}

deleteFileAfterSend(true)파일을 삭제하다my-package.zip서버로부터 액세스 합니다.

옷 갈아입는 거 잊지 마/MY_FOLDER_PATH/다운로드할 폴더 경로를 지정합니다.

저는 대본에서 약간의 개선을 했습니다.

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

이 투고를 읽고 절대 경로로 파일을 압축하지 않고(파일 압축만 하고 다른 은 하지 않음) addFromString 대신 addFile을 사용하여 파일을 압축해야 하는 이유를 찾으시는 분은 여기를 참조하십시오.

에는, 다음의 모든 서브 코드가 포함됩니다.

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

모든 것을 올바르게 하고 있다고 확신해도, 아직 동작하고 있지 않은 경우.PHP(사용자) 권한을 확인합니다.

언급URL : https://stackoverflow.com/questions/4914750/how-to-zip-a-whole-folder-using-php

반응형