วิธีการ zip ทั้งโฟลเดอร์โดยใช้ PHP


131

ฉันพบที่นี่ที่ stackoveflow รหัสบางส่วนเกี่ยวกับวิธีการ ZIP ไฟล์เฉพาะ แต่วิธีการเกี่ยวกับโฟลเดอร์ที่เฉพาะเจาะจง?

Folder/
  index.html
  picture.jpg
  important.txt

ข้างในMy Folderมีไฟล์ หลังจากซิปMy Folderแล้วฉันยังต้องการลบเนื้อหาทั้งหมดของโฟลเดอร์ยกเว้นimportant.txtฉันยังต้องการลบเนื้อหาทั้งหมดของโฟลเดอร์ยกเว้น

พบที่นี่ที่กองซ้อน

ฉันต้องการความช่วยเหลือจากคุณ. ขอบคุณ


เท่าที่ฉันเห็นลิงก์สแต็คโอเวอร์โฟลว์ที่คุณให้ไว้จะบีบไฟล์หลายไฟล์ ส่วนไหนที่คุณมีปัญหากับ
Lasse Espeholt

@lasseespeholt ลิงก์ที่ฉันให้คุณเป็นไฟล์ซิปเฉพาะไฟล์เท่านั้นไม่ใช่ไฟล์และเนื้อหาของโฟลเดอร์ ..
woninana

เขาใช้อาเรย์ของไฟล์ (เป็นโฟลเดอร์หลัก) และเพิ่มไฟล์ทั้งหมดลงในไฟล์ zip (ลูป) ฉันเห็นคำตอบที่ดีถูกโพสต์ในขณะนี้ +1 :) ซึ่งเป็นรหัสเดียวกันอาเรย์เป็นเพียงรายการไฟล์จากไดเรกทอรีทันที
Lasse Espeholt


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

คำตอบ:


320

อัปเดตรหัส 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);
}

2
คุณต้องตั้งค่า chmod (เขียนได้) บน dir (ซึ่งตั้งอยู่ที่สคริปต์นี้) ถึง 777 ตัวอย่างเช่น: หากสคริปต์อยู่ใน /var/www/localhost/script.php คุณต้องตั้งค่า chmod 0777 บน dir / var / www / localhost /
Dador

3
การลบไฟล์ก่อนที่จะโทร$zip->close()จะไม่ทำงาน ตรวจสอบคำตอบของฉันที่นี่
hek2mgl

10
@alnassre ที่เป็นข้อกำหนดจากคำถาม: "ฉันต้องการลบเนื้อหาทั้งหมดของโฟลเดอร์ยกเว้น important.txt" นอกจากนี้ฉันขอแนะนำให้คุณอ่านรหัสก่อนดำเนินการ
Dador

1
@alnassre hahahaha ... ขอโทษ :) ... hahaha
Ondrej Rafaj

1
@ nick-newman ใช่การคำนวณเปอร์เซ็นต์คุณสามารถใช้php.net/manual/ru/function.iterator-count.php + ตัวนับภายในลูป เกี่ยวกับระดับการบีบอัด - ไม่สามารถทำได้ด้วย ZipArchive ในขณะนี้: stackoverflow.com/questions/1833168/…
Dador

54

มีวิธีการที่ไม่มีเอกสารที่เป็นประโยชน์ในคลาส 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


2
@netcoder - ประโยชน์ของการเขียน phpt สำหรับการทดสอบ ... โดยทั่วไปอ่านจากแหล่งที่มาสำหรับคลาส ZipArchive และพบว่ามี ... แต่ฉันไม่เคยจัดการทำงานให้ได้ (อาจเป็นข้อผิดพลาดในชั้นเรียน)
Mark Baker

1
@kread - คุณสามารถใช้สิ่งนี้กับรายการไฟล์ที่สามารถแตกได้โดยใช้ glob () ดังนั้นฉันจึงพบว่ามันมีประโยชน์อย่างยิ่งตั้งแต่ฉันค้นพบมัน
Mark Baker

@ MarkBaker ฉันรู้ว่าความคิดเห็นนี้ผ่านมาหลายปีหลังจากที่คุณโพสต์ฉันแค่เสี่ยงโชคที่นี่ ฉันโพสต์คำถามที่นี่เกี่ยวกับการซิปด้วย ฉันกำลังจะลองวิธี glob ที่คุณโพสต์ที่นี่ แต่ปัญหาหลักของฉันคือฉันไม่สามารถใช้ addFromString และใช้ addFile ซึ่งเพิ่งล้มเหลวอย่างเงียบ ๆ คุณอาจมีความคิดใด ๆ ว่าเกิดอะไรขึ้นหรือฉันอาจทำผิด
Skytiger

@ user1032531 - บรรทัดสุดท้ายของโพสต์ของฉัน (แก้ไขเมื่อวันที่ 13 ธันวาคม 2556) ระบุว่ามีลิงก์ไปยังหน้าเอกสาร
Mark Baker

6
คือaddGlobrecursive?
Vincent Poirier

20

ลองสิ่งนี้:

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

สิ่งนี้จะไม่ซิปซ้ำ


แน่นอนว่าจะลบบางไฟล์ในMy folderแต่ฉันมีโฟลเดอร์ภายในโฟลเดอร์My folderที่ทำให้ฉันมีข้อผิดพลาด: การอนุญาตถูกปฏิเสธโดยการยกเลิกการเชื่อมโยงโฟลเดอร์ด้วย inMy folder
woninana

@Stefefy: ลองif (!is_dir($file) && $file != 'target_folder...')แทน หรือตรวจสอบ@kread คำตอบหากคุณต้องการซิปซ้ำมันเป็นวิธีที่มีประสิทธิภาพมากที่สุด
netcoder

โฟลเดอร์ภายในMy folderยังคงไม่ถูกลบ แต่ไม่มีข้อผิดพลาดอีกต่อไป
woninana

ฉันลืมพูดถึงว่าฉันไม่มีไฟล์. zip ที่สร้างขึ้น
woninana

1
การลบไฟล์ก่อนที่จะโทร$zip->close()จะไม่ทำงาน ตรวจสอบคำตอบของฉันที่นี่
hek2mgl

19

ฉันคิดว่านี่กำลังทำงานบนเซิร์ฟเวอร์ที่แอปพลิเคชัน zip อยู่ในเส้นทางการค้นหา ควรเป็นจริงสำหรับทุกระบบปฏิบัติการยูนิกซ์และฉันเดาเซิร์ฟเวอร์ส่วนใหญ่ที่ใช้ windows

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

ไฟล์เก็บถาวรจะอยู่ในไฟล์ archive.zip หลังจากนั้น โปรดทราบว่าช่องว่างในชื่อไฟล์หรือโฟลเดอร์เป็นสาเหตุของข้อผิดพลาดทั่วไปและควรหลีกเลี่ยงหากเป็นไปได้


15

ฉันลองด้วยรหัสด้านล่างและมันใช้งานได้ รหัสอธิบายตนเองโปรดแจ้งให้เราทราบหากคุณมีข้อสงสัย

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

ทางออกที่ดีเยี่ยม มันทำงานใน laravel 5.5 ด้วย ชอบที่จริง ๆ (y)
เว็บ Artisan

1
รหัสที่ดี! สะอาดเรียบง่ายและทำงานได้อย่างสมบูรณ์แบบ! ;) ดูเหมือนว่าคำตอบที่ดีที่สุดสำหรับฉัน หากสามารถช่วยใครบางคน: ฉันเพิ่งเพิ่มini_set('memory_limit', '512M');ก่อนที่จะดำเนินการของสคริปต์และini_restore('memory_limit');ในตอนท้าย จำเป็นที่จะต้องหลีกเลี่ยงการขาดหน่วยความจำในกรณีของโฟลเดอร์หนัก (เป็นโฟลเดอร์ที่มีขนาดใหญ่กว่า 500MB)
Jacopo Pace

1
ในสภาพแวดล้อมของฉัน (PHP 7.3, Debian) ไฟล์ ZIP ที่ไม่มีรายการไดเรกทอรีถูกสร้างขึ้น (ไฟล์ใหญ่และว่างเปล่า) ฉันต้องเปลี่ยนบรรทัดต่อไปนี้: $ name. = '/'; เป็น $ name = ($ name == '.'? '': $ name. '/');
Gerfried

มันใช้งานได้สำหรับฉัน ขอบคุณสำหรับการแบ่งปัน. ไชโย!
Sathiska

8

นี่คือฟังก์ชั่นที่ซิปไฟล์ทั้งโฟลเดอร์และเนื้อหาในไฟล์ 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";
}

จะรวมโฟลเดอร์ย่อยในการสำรองข้อมูลโดยอัตโนมัติด้วยสคริปต์นี้ได้อย่างไร @Alireza
floCoder

2

ทำไมไม่ลอง สคริปต์ MultiVolume EFS PhP-ZiP ... ฉันซิปและถ่ายโอนหลายร้อยกิ๊กและไฟล์นับล้าน ... ต้องใช้ ssh เพื่อสร้างคลังข้อมูลอย่างมีประสิทธิภาพ

แต่ฉันเชื่อว่าไฟล์ผลลัพธ์สามารถใช้กับ exec โดยตรงจาก php:

exec('zip -r backup-2013-03-30_0 . -i@backup-2013-03-30_0.txt');

ฉันไม่ทราบว่ามันใช้งานได้ ฉันยังไม่ได้ลอง ...

"ความลับ" คือเวลาดำเนินการสำหรับการเก็บถาวรไม่ควรเกินเวลาที่อนุญาตให้เรียกใช้งานโค้ด PHP


1

นี่เป็นตัวอย่างการทำงานของการสร้าง 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();

1

ฉันพบโพสต์นี้ใน 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];
    }
?>

มันทำอะไร??

มันจะทำการ zip เนื้อหาทั้งหมดของตัวแปร $ pathBase และเก็บ zip ไว้ในโฟลเดอร์เดียวกัน มันตรวจจับได้ง่ายสำหรับการสำรองข้อมูลก่อนหน้าและข้ามมัน

สำรอง CRON

สคริปต์นี้ฉันเพิ่งทดสอบบน linux และทำงานได้ดีจากงาน cron ด้วยการใช้ url สัมบูรณ์สำหรับ pathBase


ฉันได้ยกเว้นการลบสคริปต์คุณสามารถดูคำตอบที่ได้รับการยอมรับ
Angry 84

ต้องรักคะแนนโหวตแบบสุ่มเหล่านั้นโดยไม่มีความคิดเห็นอธิบายว่าทำไม
โกรธ 84

1

ใช้ฟังก์ชั่นนี้:

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

1

ใช้สิ่งนี้ทำงานได้ดี

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

1

สร้างโฟลเดอร์ zip ใน PHP

วิธีสร้าง 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);

0

ฉันปรับปรุงสคริปต์เล็กน้อย

  <?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 ไฟล์ แต่รายชื่อไดเรกทอรีหายไปแล้วมันไม่มีไดเรกทอรีอีกต่อไป
23715 Sujay sreedhar

0

นี่จะช่วยแก้ปัญหาของคุณ โปรดลอง

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

0

สำหรับใครก็ตามที่อ่านโพสต์นี้และมองหาสาเหตุที่ทำให้ zip ไฟล์โดยใช้ addFile แทนที่จะเป็น addFromString นั่นไม่ได้ทำการซิปไฟล์ด้วยพา ธ สัมบูรณ์ของพวกเขา (เพียงแค่ซิปไฟล์และไม่มีอะไรอื่น) ดูคำถามและคำตอบของฉันที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.