วิธี [เรียกซ้ำ] Zip ไดเรกทอรีใน PHP?


118

ไดเรกทอรีเป็นสิ่งที่ต้องการ:

home/
    file1.html
    file2.html
Another_Dir/
    file8.html
    Sub_Dir/
        file19.html

ฉันใช้เรียน PHP ซิปเดียวกับที่ใช้ใน PHPMyAdmin http://trac.seagullproject.org/browser/branches/0.6-bugfix/lib/other/Zip.php ฉันไม่แน่ใจว่าจะซิปไดเร็กทอรีไม่ใช่แค่ไฟล์ นี่คือสิ่งที่ฉันมีจนถึงตอนนี้:

$aFiles = $this->da->getDirTree($target);
/* $aFiles is something like, path => filetime
Array
(
    [home] => 
    [home/file1.html] => 1251280379
    [home/file2.html] => 1251280377
    etc...
)

*/
$zip = & new Zip();
foreach( $aFiles as $fileLocation => $time ){
    $file = $target . "/" . $fileLocation;
    if ( is_file($file) ){
        $buffer = file_get_contents($file);
        $zip->addFile($buffer, $fileLocation);
    }
}
THEN_SOME_PHP_CLASS::toDownloadData($zip); // this bit works ok

แต่เมื่อฉันพยายามคลายซิปไฟล์ zip ที่ดาวน์โหลดมาฉันได้รับ "การดำเนินการไม่ได้รับอนุญาต"

ข้อผิดพลาดนี้เกิดขึ้นเฉพาะเมื่อฉันพยายามคลายซิปบนเครื่อง Mac ของฉันเมื่อฉันเปิดเครื่องรูดผ่านบรรทัดคำสั่งไฟล์จะคลายซิปได้ ฉันจำเป็นต้องส่งประเภทเนื้อหาเฉพาะเมื่อดาวน์โหลดซึ่งปัจจุบันเป็น "แอปพลิเคชัน / zip"


รหัสนี้ใช้งานได้จริง - แต่ด้วยเหตุผลบางประการคุณไม่สามารถเปิดเครื่องรูดบน Mac OS ได้ (เว้นแต่คุณจะใช้การคลายซิป CLI) ไฟล์ Zip unstuffs ตกลงบนพีซี
ed209

สิ่งนี้สามารถช่วยคุณcodingbin.com/compressing-a-directory-of-files-with-php
MKD

คำตอบ:


253

นี่คือฟังก์ชั่นง่ายๆที่สามารถบีบอัดไฟล์หรือไดเร็กทอรีแบบวนซ้ำได้โดยต้องโหลดเฉพาะส่วนขยาย zip เท่านั้น

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 . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

เรียกแบบนี้ว่า

Zip('/folder/to/compress/', './compressed.zip');

5
ทำงานได้ดีมากคำถามเดียวของฉันคือสคริปต์ของฉันทำงานจากตำแหน่งอื่นไปยังไฟล์ที่จะถูกบีบอัดดังนั้นเมื่อฉันระบุอาร์กิวเมนต์แรกที่ใช้ตำแหน่ง filepath แบบเต็มภายใน zip เช่น: C: \ wamp \ www \ export \ pkg-1211.191011 \ pkg-1211.191011.zip ซึ่งโครงสร้างโฟลเดอร์ที่ซ้อนกันแบบเต็มจะอยู่ภายในไฟล์เก็บถาวรใหม่ มีวิธีปรับสคริปต์ข้างต้นให้มีเฉพาะไฟล์และไดเร็กทอรีที่ฉันชี้ไปและไม่ใช่เส้นทางแบบเต็มหรือไม่?
danjah

4
@ Danjah: ฉันได้อัปเดตโค้ดแล้วควรใช้ได้กับทั้ง * nix และ Windows ในขณะนี้
Alix Axel

6
ฉันสงสัยว่าเหตุใดจึงใช้file_get_contentsและเพิ่มสตริง zip ไม่รองรับการเพิ่มไฟล์โดยตรง?
hakre

4
คุณต้องแทนที่ทั้งหมด'/'ที่มีDIRECTORY_SEPARATORเพื่อให้ทำงานบน Windows ของหลักสูตร มิฉะนั้นคุณจะจบลงด้วยเส้นทางแบบเต็ม (รวมทั้งชื่อไดรฟ์) C:\Users\...ในไปรษณีย์ของคุณเช่น
caw

3
รหัสเดิมถูก / เสียและซ้ำซ้อน ไม่จำเป็นต้องแทนที่//ด้วย\ เนื่องจากสิ่งนี้จะทำลาย foreach บน windows หากคุณใช้ในตัวDIRECTORY_SEPARATORเท่าที่ควรไม่จำเป็นต้องเปลี่ยน การเข้ารหัส/คือสิ่งที่ทำให้ผู้ใช้บางรายมีปัญหา ฉันสับสนเล็กน้อยว่าทำไมฉันถึงได้รับที่เก็บถาวรว่างเปล่า การแก้ไขของฉันจะทำงานได้ดีภายใต้ * nix และ Windows
DavidScherer

18

ยังมีการจัดเก็บแผนผังไดเร็กทอรีแบบเรียกซ้ำอีกรายการซึ่งใช้เป็นส่วนขยายของ ZipArchive เป็นโบนัสฟังก์ชันตัวช่วยการบีบอัดต้นไม้คำสั่งเดียวรวมอยู่ด้วย รองรับ localname เสริมเช่นเดียวกับในฟังก์ชัน ZipArchive อื่น ๆ เกิดข้อผิดพลาดในการจัดการรหัสที่จะเพิ่ม ...

class ExtendedZip extends ZipArchive {

    // Member function to add a whole file system subtree to the archive
    public function addTree($dirname, $localname = '') {
        if ($localname)
            $this->addEmptyDir($localname);
        $this->_addTree($dirname, $localname);
    }

    // Internal function, to recurse
    protected function _addTree($dirname, $localname) {
        $dir = opendir($dirname);
        while ($filename = readdir($dir)) {
            // Discard . and ..
            if ($filename == '.' || $filename == '..')
                continue;

            // Proceed according to type
            $path = $dirname . '/' . $filename;
            $localpath = $localname ? ($localname . '/' . $filename) : $filename;
            if (is_dir($path)) {
                // Directory: add & recurse
                $this->addEmptyDir($localpath);
                $this->_addTree($path, $localpath);
            }
            else if (is_file($path)) {
                // File: just add
                $this->addFile($path, $localpath);
            }
        }
        closedir($dir);
    }

    // Helper function
    public static function zipTree($dirname, $zipFilename, $flags = 0, $localname = '') {
        $zip = new self();
        $zip->open($zipFilename, $flags);
        $zip->addTree($dirname, $localname);
        $zip->close();
    }
}

// Example
ExtendedZip::zipTree('/foo/bar', '/tmp/archive.zip', ZipArchive::CREATE);

คำตอบที่ดี Giorgio! ให้ผลลัพธ์ที่ดีกว่า Zip () บน windows สำหรับโครงสร้างต้นไม้ ขอบคุณ
RafaSashi

11

ฉันได้แก้ไขคำตอบของAlix Axelเพื่อรับอาร์กิวเมนต์ที่สามเมื่อตั้งค่าอาร์กิวเมนต์ที่สามนี้เป็นtrueกับไฟล์ทั้งหมดจะถูกเพิ่มภายใต้ไดเร็กทอรีหลักแทนที่จะอยู่ในโฟลเดอร์ zip โดยตรง

หากมีไฟล์ zip อยู่ไฟล์ก็จะถูกลบเช่นกัน

ตัวอย่าง:

Zip('/path/to/maindirectory','/path/to/compressed.zip',true);

trueโครงสร้างซิปที่สาม:

maindirectory
--- file 1
--- file 2
--- subdirectory 1
------ file 3
------ file 4
--- subdirectory 2
------ file 5
------ file 6

falseโครงสร้างซิปที่สามหรือขาดหายไป:

file 1
file 2
subdirectory 1
--- file 3
--- file 4
subdirectory 2
--- file 5
--- file 6

แก้ไขรหัส:

function Zip($source, $destination, $include_dir = false)
{

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

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

        if ($include_dir) {

            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= '/' . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        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 . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

ขอบคุณ! ฉันต้องการรวมไดเร็กทอรีหลักในสถานการณ์ของฉัน
Kim Stacks

ฟังก์ชันของคุณไม่ทำงานเฉพาะไดเร็กทอรีหลัก (รูท) เท่านั้นที่เพิ่มและไม่มีอะไรเลย
Krishna Torque

ฉันรู้ว่าคำตอบนี้นานมาแล้ว เป็นไปได้ไหมที่จะมีชื่อที่กำหนดเองสำหรับ 'maindirectory' แทนชื่อเดิม
Vaibhav Sidapara

@VaibhavSidapara เชื่อว่าน่าจะทำได้โดยเปลี่ยน$maindirเป็นชื่อที่ต้องการ
user2019515

คำตอบที่ดีช่วยฉันมาก ฉันได้เพิ่มอาร์กิวเมนต์ที่สี่ในฟังก์ชันนี้เพื่อรวมการยกเว้น ฉันจะเพิ่มรหัสสุดท้ายเป็นคำตอบอื่นสำหรับคำถามนี้
L. Ouellet

4

การใช้งาน: thisfile.php? dir =. / path / to / folder (หลังจากซิปไฟล์จะเริ่มดาวน์โหลดด้วย :)

<?php
$exclude_some_files=
array(
        'mainfolder/folder1/filename.php',
        'mainfolder/folder5/otherfile.php'
);

//***************built from https://gist.github.com/ninadsp/6098467 ******
class ModifiedFlxZipArchive extends ZipArchive {
    public function addDirDoo($location, $name , $prohib_filenames=false) {
        if (!file_exists($location)) {  die("maybe file/folder path incorrect");}

        $this->addEmptyDir($name);
        $name .= '/';
        $location.= '/';
        $dir = opendir ($location);   // Read all Files in Dir

        while ($file = readdir($dir)){
            if ($file == '.' || $file == '..') continue;
            if (!in_array($name.$file,$prohib_filenames)){
                if (filetype( $location . $file) == 'dir'){
                    $this->addDirDoo($location . $file, $name . $file,$prohib_filenames );
                }
                else {
                    $this->addFile($location . $file, $name . $file);
                }
            }
        }
    }

    public function downld($zip_name){
        ob_get_clean();
        header("Pragma: public");   header("Expires: 0");   header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
        header("Cache-Control: private", false);    header("Content-Type: application/zip");
        header("Content-Disposition: attachment; filename=" . basename($zip_name) . ";" );
        header("Content-Transfer-Encoding: binary");
        header("Content-Length: " . filesize($zip_name));
        readfile($zip_name);
    }
}

//set memory limits
set_time_limit(3000);
ini_set('max_execution_time', 3000);
ini_set('memory_limit','100M');
$new_zip_filename='down_zip_file_'.rand(1,1000000).'.zip';  
// Download action
if (isset($_GET['dir']))    {
    $za = new ModifiedFlxZipArchive;
    //create an archive
    if  ($za->open($new_zip_filename, ZipArchive::CREATE)) {
        $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close();
    }else {die('cantttt');}

if (isset($_GET['dir']))    {
    $za = new ModifiedFlxZipArchive;
    //create an archive
    if  ($za->open($new_zip_filename, ZipArchive::CREATE)) {
        $za->addDirDoo($_GET['dir'], basename($_GET['dir']), $exclude_some_files); $za->close();
    }else {die('cantttt');}

    //download archive
    //on the same execution,this made problems in some hostings, so better redirect
    //$za -> downld($new_zip_filename);
    header("location:?fildown=".$new_zip_filename); exit;
}   
if (isset($_GET['fildown'])){
    $za = new ModifiedFlxZipArchive;
    $za -> downld($_GET['fildown']);
}
?>

2

ลองใช้ลิงก์นี้ <- รหัสแหล่งข้อมูลเพิ่มเติมที่นี่

/** Include the Pear Library for Zip */
include ('Archive/Zip.php');

/** Create a Zipping Object...
* Name of zip file to be created..
* You can specify the path too */
$obj = new Archive_Zip('test.zip');
/**
* create a file array of Files to be Added in Zip
*/
$files = array('black.gif',
'blue.gif',
);

/**
* creating zip file..if success do something else do something...
* if Error in file creation ..it is either due to permission problem (Solution: give 777 to that folder)
* Or Corruption of File Problem..
*/

if ($obj->create($files)) {
// echo 'Created successfully!';
} else {
//echo 'Error in file creation';
}

?>; // We'll be outputting a ZIP
header('Content-type: application/zip');

// It will be called test.zip
header('Content-Disposition: attachment; filename="test.zip"');

//read a file and send
readfile('test.zip');
?>;

1

นี่คือรหัสของฉันสำหรับ Zip โฟลเดอร์และโฟลเดอร์ย่อยและไฟล์และทำให้ดาวน์โหลดได้ในรูปแบบ zip

function zip()
 {
$source='path/folder'// Path To the folder;
$destination='path/folder/abc.zip'// Path to the file and file name ; 
$include_dir = false;
$archive = 'abc.zip'// File Name ;

if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

if (file_exists($destination)) {
    unlink ($destination);
}

$zip = new ZipArchive;

if (!$zip->open($archive, ZipArchive::CREATE)) {
    return false;
}
$source = str_replace('\\', '/', realpath($source));
if (is_dir($source) === true)
{

    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    if ($include_dir) {

        $arr = explode("/",$source);
        $maindir = $arr[count($arr)- 1];

        $source = "";
        for ($i=0; $i < count($arr) - 1; $i++) { 
            $source .= '/' . $arr[$i];
        }

        $source = substr($source, 1);

        $zip->addEmptyDir($maindir);

    }

    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 . '/'));
        }
        else if (is_file($file) === true)
        {
            $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
        }
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}
$zip->close();

header('Content-Type: application/zip');
header('Content-disposition: attachment; filename='.$archive);
header('Content-Length: '.filesize($archive));
readfile($archive);
unlink($archive);
}

หากมีปัญหาเกี่ยวกับรหัสแจ้งให้เราทราบ


0

ฉันต้องการเรียกใช้ฟังก์ชัน Zip นี้ใน Mac OSX

ดังนั้นฉันมักจะซิป. DS_Store ที่น่ารำคาญ

ฉันปรับhttps://stackoverflow.com/users/2019515/user2019515โดยรวมไฟล์เพิ่มเติมละเว้น

function zipIt($source, $destination, $include_dir = false, $additionalIgnoreFiles = array())
{
    // Ignore "." and ".." folders by default
    $defaultIgnoreFiles = array('.', '..');

    // include more files to ignore
    $ignoreFiles = array_merge($defaultIgnoreFiles, $additionalIgnoreFiles);

    if (!extension_loaded('zip') || !file_exists($source)) {
        return false;
    }

    if (file_exists($destination)) {
        unlink ($destination);
    }

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

        if ($include_dir) {

            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];

            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) { 
                $source .= '/' . $arr[$i];
            }

            $source = substr($source, 1);

            $zip->addEmptyDir($maindir);

        }

        foreach ($files as $file)
        {
            $file = str_replace('\\', '/', $file);

            // purposely ignore files that are irrelevant
            if( in_array(substr($file, strrpos($file, '/')+1), $ignoreFiles) )
                continue;

            $file = realpath($file);

            if (is_dir($file) === true)
            {
                $zip->addEmptyDir(str_replace($source . '/', '', $file . '/'));
            }
            else if (is_file($file) === true)
            {
                $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file));
            }
        }
    }
    else if (is_file($source) === true)
    {
        $zip->addFromString(basename($source), file_get_contents($source));
    }

    return $zip->close();
}

ดังนั้นเพื่อละเว้น. DS_Store จาก zip คุณเรียกใช้

zipIt ('/ path / to / folder', '/path/to/compressed.zip', false, array ('. DS_Store'));


0

ทางออกที่ดี แต่สำหรับ Windows ของฉันฉันต้องทำการปรับเปลี่ยน ด้านล่างรหัสแก้ไข

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;

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . '/', '', $file));
        }
        else if (is_file($file) === true)
        {

            $str1 = str_replace($source . '/', '', '/'.$file);
            $zip->addFromString($str1, file_get_contents($file));

        }
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}

return $zip->close();
}

0

รหัสนี้ใช้ได้กับทั้ง windows และ linux

function Zip($source, $destination)
{
if (!extension_loaded('zip') || !file_exists($source)) {
    return false;
}

$zip = new ZipArchive();
if (!$zip->open($destination, ZIPARCHIVE::CREATE)) {
    return false;
}

if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
    DEFINE('DS', DIRECTORY_SEPARATOR); //for windows
} else {
    DEFINE('DS', '/'); //for linux
}


$source = str_replace('\\', DS, realpath($source));

if (is_dir($source) === true)
{
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);
    echo $source;
    foreach ($files as $file)
    {
        $file = str_replace('\\',DS, $file);
        // Ignore "." and ".." folders
        if( in_array(substr($file, strrpos($file, DS)+1), array('.', '..')) )
            continue;

        $file = realpath($file);

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(str_replace($source . DS, '', $file . DS));
        }
        else if (is_file($file) === true)
        {
            $zip->addFromString(str_replace($source . DS, '', $file), file_get_contents($file));
        }
        echo $source;
    }
}
else if (is_file($source) === true)
{
    $zip->addFromString(basename($source), file_get_contents($source));
}

return $zip->close();
}

0

นี่คือฐานเวอร์ชันของฉันบน Alix ทำงานบน Windows และหวังว่าจะใช้ * nix ด้วย:

function addFolderToZip($source, $destination, $flags = ZIPARCHIVE::OVERWRITE)
{
    $source = realpath($source);
    $destination = realpath($destination);

    if (!file_exists($source)) {
        die("file does not exist: " . $source);
    }

    $zip = new ZipArchive();
    if (!$zip->open($destination, $flags )) {
        die("Cannot open zip archive: " . $destination);
    }

    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST);

    $sourceWithSeparator = $source . DIRECTORY_SEPARATOR;
    foreach ($files as $file)
    {
        // Ignore "." and ".." folders
        if(in_array(substr($file,strrpos($file, DIRECTORY_SEPARATOR)+1),array('.', '..')))
            continue;

        if (is_dir($file) === true)
        {
            $zip->addEmptyDir(
                str_replace($sourceWithSeparator, '', $file . DIRECTORY_SEPARATOR));
        }
        else if (is_file($file) === true)
        {
            $zip->addFile($file, str_replace($sourceWithSeparator, '', $file));
        }
    }

    return $zip->close();
}

0

นี่คือฟังก์ชั่นเรียกซ้ำที่ง่ายอ่านง่ายซึ่งทำงานได้ดีมาก:

function zip_r($from, $zip, $base=false) {
    if (!file_exists($from) OR !extension_loaded('zip')) {return false;}
    if (!$base) {$base = $from;}
    $base = trim($base, '/');
    $zip->addEmptyDir($base);
    $dir = opendir($from);
    while (false !== ($file = readdir($dir))) {
        if ($file == '.' OR $file == '..') {continue;}

        if (is_dir($from . '/' . $file)) {
            zip_r($from . '/' . $file, $zip, $base . '/' . $file);
        } else {
            $zip->addFile($from . '/' . $file, $base . '/' . $file);
        }
    }
    return $zip;
}
$from = "/path/to/folder";
$base = "basezipfolder";
$zip = new ZipArchive();
$zip->open('zipfile.zip', ZIPARCHIVE::CREATE);
$zip = zip_r($from, $zip, $base);
$zip->close();

0

ตามคำตอบของ @ user2019515 ฉันจำเป็นต้องจัดการการยกเว้นในที่เก็บถาวรของฉัน นี่คือฟังก์ชันผลลัพธ์พร้อมตัวอย่าง

ฟังก์ชัน Zip:

function Zip($source, $destination, $include_dir = false, $exclusions = false){
    // Remove existing archive
    if (file_exists($destination)) {
        unlink ($destination);
    }

    $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);
        if ($include_dir) {
            $arr = explode("/",$source);
            $maindir = $arr[count($arr)- 1];
            $source = "";
            for ($i=0; $i < count($arr) - 1; $i++) {
                $source .= '/' . $arr[$i];
            }
            $source = substr($source, 1);
            $zip->addEmptyDir($maindir);
        }
        foreach ($files as $file){
            // Ignore "." and ".." folders
            $file = str_replace('\\', '/', $file);
            if(in_array(substr($file, strrpos($file, '/')+1), array('.', '..'))){
                continue;
            }

            // Add Exclusion
            if(($exclusions)&&(is_array($exclusions))){
                if(in_array(str_replace($source.'/', '', $file), $exclusions)){
                    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();
}

วิธีใช้:

function backup(){
    $backup = 'tmp/backup-'.$this->site['version'].'.zip';
    $exclusions = [];
    // Excluding an entire directory
    $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator('tmp/'), RecursiveIteratorIterator::SELF_FIRST);
    foreach ($files as $file){
        array_push($exclusions,$file);
    }
    // Excluding a file
    array_push($exclusions,'config/config.php');
    // Excluding the backup file
    array_push($exclusions,$backup);
    $this->Zip('.',$backup, false, $exclusions);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.