แนะนำ PhpZip PHP Library สำหรับจัดการไฟล์ Zip

บทความใหม่ สัปดาห์นี้ โดย Ninenik Narkdee
zip phpzip php library

คำสั่ง การ กำหนด รูปแบบ ตัวอย่าง เทคนิค ลูกเล่น การประยุกต์ การใช้งาน เกี่ยวกับ zip phpzip php library



เนื้อหานี้จะมาแนะนำการใช้งาน PHP Library สำหรับ
ทำการบีบอัดไฟล์หรือที่เราคุ้นกับคำว่า zip ไฟล์ ซึ่งมีประโยชน์มาก
สำหรับการประยุกต์ใช้งาน เช่น การ backup ไฟล์ หรือข้อมูลเนื้อหาต่างๆ
การดาวน์โหลดไฟล์ การนำไปปรับใช้กับระบบจัดการหรือการติดตั้ง module
ผ่าน zip ไฟล์ เหล่านี้เป็นต้น สามารถศึกษาเพิ่มเติมด้วยตัวเองได้ที่
 
    ลักษณะเด่นของ Library นี้คือ
      - เปิดและแตกไฟล์ zip
      - สร้าง zip ไฟล์ใหม่
      - แก้ไขข้อมูลไฟล์ zip อย่างเช่น การเพิ่มไฟล์ใหม่เข้าไปใน zip ไฟล์
      - สร้างไฟล์ zip และบันทึกเป็นไฟล์ หรือดาวน์โหลดโดยไม่ต้องบันทึกเป็นไฟล์ก็ได้
      - รองรับรูปแบบ ZIP64 ที่สามารถ zip ไฟล์ได้ถึงขนาด 4 GB และจำนวนไฟล์ได้มากกว่า 65535 ไฟล์
 
 
 

การติดตั้ง PhpZip Library

    สามารถติดตั้งผ่าน composer ด้วยคำสั่ง
 
composer require nelexa/zip
 
    กรณีโปรเจ็คของเรามีการใช้งาน vendor โฟลเดอร์อยู่แล้ว แต่ไม่ต้องการจะใช้งาน หรือใช้ Library นี้เพิ่มเข้ามา
กับตัวเดิม หรือกรณีเราไม่มีการใช้งาน vendor เลย แต่ต้องการใช้งาน Library นี้ เราสามารถสร้างโฟลเดอร์
temp หรือโฟลเดอร์อะไรก็ได้ มาไว้ใน htdocs หรือ root ของ localhost สมมติใช้เป็น temp1 จากนั้นติดตั้ง
ด้วยคำสั่ง composer ด้านบนตามตัวอย่าง

 

 
 
    จากนั้นเราจะได้โฟลเดอร์ vendor สามารถ copy ไปไว้ส่วนไหนของ server แล้วเรียกใช้งานก็ได้

 

 
 
    ใครไม่อยากติดตั้งเอง สามารถดาวน์โหลด เวอร์ชั่น 3.3 ได้ที่ https://bit.ly/34EwTto
 
 
 

เตรียมส่วนของประยุกต์ใช้งาน

    เราจะจำลองการนำไปใช้งาน โดยจะ copy โฟลเดอร์ vendor มาไว้ในโฟลเดอร์ phpzip ตามรูปด้านล่าง
พร้อมโค้ดการเรียกใช้งานในไฟล์ชื่อ demo_zip.php

 

 
 

 
 
    ไฟล์ demo_zip.php
 
<?php
// include composer autoload
require_once './vendor/autoload.php';  // กำหนด path ให้ถูกต้อง

// create new archive
$zipFile = new \PhpZip\ZipFile();
$outputFilename = "test.zip";
try{

    $zipFile
        ->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
        ->saveAsFile($outputFilename) // บันทึก zip ไฟล์
        ->close(); // close archive
           
}
catch(\PhpZip\Exception\ZipException $e){
    // จัดการข้อผิดพลาด ทำคำสั่งตามต้องการถ้ามี
}
finally{
    $zipFile->close();
}
?>
 
    ทดสอบรันไฟล์ข้างต้นผ่าน บราวเซอร์ 
 
 

 
 
    เนื่องจากเราไม่ได้กำหนดให้แสดงข้อความใดๆ เมื่อมีการทำงาน จึงไม่มีข้อมูลแสดงทาง บราวเซอร์ แต่เราจะได้
ไฟล์ test.zip ถูกบันทึกเป็นไฟล์ ตามที่เรากำหนด

 

 
 
    และถ้าเราลองเปิดไฟล์ zip ก็จะมีไฟล์ด้านในเป็นไฟล์ demo_zip.php หรือไฟล์ที่อยู่ในโฟลเดอร์ปัจจุบัน

 

 
 
    นี่คือหลักการทำงานคร่าวๆ ของการสร้างไฟล์ zip คือ กำหนดไฟล์ที่จะทำการ zip  ไฟล์หรือส่วนที่กำหนดจะถูกนำ
รวมกันเป็น zip ไฟล์ และต่อด้วยการบันทึกเป็นไฟล์ zip หรือไฟล์ดาวน์โหลด ตามชื่อที่กำหนด  
    ถ้าเราดูในส่วนของการทำงานของคำสั่ง จะมีรูปแบบง่ายๆ 
 
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->saveAsFile($outputFilename) // บันทึก zip ไฟล์
	->close(); // close archive
 
    คำสั่ง addDir() ช่วยให้เราสามารถเพิ่มไฟล์ทั้งหมดในโฟลเดอร์ที่ระบุ โดยไม่ต้องระบุชื่อไฟล์ เข้าไปในไฟล์ zip 
    จากนั้นใช้คำสั่ง saveAsFile() เพื่อบันทึกเป็นชื่อไฟล์ตามที่เรากำหนด สามารถกำหนดชื่อพร้อม path ที่ต้องการบันทึกได้
    และจบด้วยการปิดการทำงานไฟล์ zip ไฟล์ที่ใช้งานด้วยคำสั่ง close()
 
 
 

การใช้งานและคำสั่งต่างๆ

    คำสั่งจัดการและการเปิดไฟล์ zip

 
    ในการจัดการข้อมูลไฟล์ zip เราจำเป็นจะต้องเปิดไฟล์นั้นมาก่อน ข้อมูลไฟล์ zip ที่ phpzip รองรับจะประกอบด้วย
ข้อมูลที่เป็นไฟล์ zip / ข้อมูล String ของไฟล์ zip / และข้อมูลไฟล์ zip ที่เป็นแบบ stream 
    ทั้ง 3 รูปแบบชนิดข้อมูล สามารถใช้คำสั่งเปิดไฟล์ได้ดังนี้
 
    openFile()
    คำสั่งเปิดไฟล์ zip เพื่อใช้งาน
 
$zipFile = new \PhpZip\ZipFile();
try{

	$zipFile->openFile('images.zip'); // เปิดไฟล์ zip ที่ต้องการ
	$count = $zipFile->count(); // คำสั่งนับจำนวนรายการในไฟล์ zip
	echo $count; // จำนวนไฟล์ และโฟลเดอร์ในไฟล์ zip

}
catch(\PhpZip\Exception\ZipException $e){
    // จัดการข้อผิดพลาด ทำคำสั่งตามต้องการถ้ามี
}
finally{
    $zipFile->close();
}
 
    ตัวอย่างข้างตัน ใช้รูปแบบข้อมุลที่เป็น zip เปิดโดยใช้คำสั่ง openFile()
 
 
    openFromString()
    ถ้าเป็น string ข้อมูลไฟล์ zip สามารถใช้คำสั่ง
 
$zipFile->openFromString($stringContents);
 
 
    openFromStream()    
    และข้อมูลที่เป็น stream สามารถใช้คำสั่ง
 
$stream = fopen('images.zip', 'rb');
$zipFile->openFromStream($stream);
 
    คำสั่ง openFile() กับ openFromStream() จะมีเรื่องของการใช้หน่วยความจำหรือการจัดการกับไฟล์ ยิ่งถ้าไฟล์
มีขนาดใหญ่ การใช้ข้อมูลที่เป็น stream จะเป็นวิธีที่เหมาะสมกว่า
 
 
    getListFiles()
    สำหรับแสดง array ข้อมูล path ไฟล์ และ โฟลเดอร์ในไฟล์ zip ดูตัวอย่าง และผลลัพธ์ข้อมูลที่ได้
 
$zipFile->openFile('images.zip');
$listFiles = $zipFile->getListFiles();
echo "<pre>";
print_r($listFiles);	
 
    ผลลัพธ์ที่ได้
 
Array
(
    [0] => Bridge.jpg
    [1] => Broken Top.jpg
    [2] => subfolder/
    [3] => subfolder/Leaves.jpg
    [4] => subfolder/sky.jpg
    [5] => water.jpg
    [6] => Yosemite.jpg
)
 
    คำสั่ง getListFiles() เราจะได้เฉพาะ path ของไฟล์ และ โฟลเดอร์ในไฟล์ zip แต่ถ้าเราต้องการแสดงข้อมูลของไฟล์ด้วย
เราสามารถวนลูปด้วยรูปแบบคำสั่งดังนี้ได้
 
$zipFile->openFile('images.zip');
foreach($zipFile as $entryName => $contents){
    // $entryName คือ path ไฟล์ และ โฟลเดอร์ในไฟล์ zip
    // $contents คือ ข้อมูลไฟล์ หรือ โฟลเดอร์นั้นๆ 
}
 
 
    getEntryContent()
    สำหรับแสดงข้อมูลของไฟล์ที่กำหนด ในไฟล์ zip เช่น สมมติว่าเรารู้ว่ามีไฟล์ชื่ออะไร และมี path อยู่ส่วนไหน
ในไฟล์ zip เราสามารถดูข้อมูลไฟล์น้้นๆ ได้ ตัวอย่าง เรามีไฟล์ sky.jpg อยู่ตามตัวอย่าง path ด้านบน เราจะเอาข้อมูล
รูปนั้นมาแสดง จะได้เป็น
 
$zipFile->openFile('images.zip');
$entryName = "subfolder/sky.jpg"; // path ไฟล์ใน zip ที่เราจะแสดงข้อมูล
$contents = $zipFile->getEntryContents($entryName);
header('Content-Type: image/jpeg'); // เนื่องจากข้อมูลเป็นไฟล์รูป ก่อนแสดงต้องกำหนดรูปแบบ
echo $contents;
 
    รูปจะแสดงผ่านบราวเซอร์ 
    จะเห็นว่า เราสามารถอ่านค่าไฟล์ข้อมูล ในไฟล์ zip มาใช้งานโดยมาต้องแตกไฟล์ zip 
 
 
    hasEntry()
    สำหรับตรวจสอบรายการในไฟล์ zip ว่ามีรายการไฟล์ หรือ โฟลเดอร์ที่กำหนดหรือไม่ คืนค่าเป็น true ถ้ามีข้อมูลนั้นๆ
 
$zipFile->openFile('images.zip');
$entryName = "subfolder/sky.jpg"; // เช็คไฟล์
// $entryName = "subfolder/"; // เช็คโฟลเดอร์ สังเกตว่าถ้าเป็น โฟลเดอร์ต้องกำหนด / ปิดท้ายด้วย
$hasEntry = $zipFile->hasEntry($entryName);
 
 
    isDirectory()
    สำหรับตรวจสอบว่ามีโฟลเดอร์ที่กำหนดในไฟล์ zip หรือไม่ คืนค่าเป็น true ถ้ามีโฟลเดอร์ที่กำหนด
 
$zipFile->openFile('images.zip');
$entryName = "subfolder/"; // เช็คโฟลเดอร์ สังเกตว่าถ้าเป็น โฟลเดอร์ต้องกำหนด / ปิดท้ายด้วย
$isDirectory = $zipFile->isDirectory($entryName);
 
    extractTo()
    สำหรับแตกไฟล์ zip ไปยังโฟลเดอร์ที่ต้องการ โดยโฟลเดอร์ที่เราระบุ จะต้องมีหรือถูกสร้างไว้รองรับเท่านั้น 
จะไม่ใช้การสร้างโฟลเดอร์และแตกไฟล์ไปยังโฟลเดอร์ที่กำหนด ดังนั้นเราต้องโฟลเดอร์ที่จะใช้งานก่อนเสมอ
 
$zipFile->openFile('images.zip');
$directory = "myzip"; // โฟลเดอร์ myzip ที่เราจะเก็บไฟล์จากไฟล์ zip
$zipFile->extractTo($directory);
 
    ถ้าเรารู้ path ไฟล์ หรือ โฟลเดอร์ ในไฟล์ zip ที่ต้องการ เราสามารถเลือกเฉพาะไฟล์ได้ โดยกำหนด array
รายการใน parameter ที่สอง ดังนี้
 
$zipFile->openFile('images.zip');
$directory = "myzip";
$extractOnlyFiles = [
    'water.jpg', 
    'subfolder/sky.jpg', 	
    'subfolder/' // จะได้เฉพาะโฟลเดอร์ ไม่ได้ไฟล์ด้านในด้วย
];
$zipFile->extractTo($directory, $extractOnlyFiles);
 
 
    getEntryInfo()
    สำหรับแสดงข้อมูลของไฟล์ที่ต้องการ ที่อยู่ในไฟล์ zip เช่น ขนาดไฟล์ทั้งก่อน และหลังบีบอัดไฟล์
 
$zipFile->openFile('images.zip');
$zipInfo = $zipFile->getEntryInfo('subfolder/sky.jpg');
echo $zipInfo->getName();
echo $zipInfo->isFolder();
echo $zipInfo->getSize();
echo $zipInfo->getCompressedSize();
echo $zipInfo->isEncrypted();
echo $zipInfo->getMethodName();
echo $zipInfo->getEncryptionMethod();
echo $zipInfo->getEncryptionMethodName();
 
 
    getAllInfo()
    สำหรับแสดงข้อมูลไฟล์ และโฟลเดอร์ทั้งหมดในไฟล์ zip เราสามารถวนลูปด้วยการจัดการ array ได้
 
$zipFile->openFile('images.zip');
$zipAllInfo = $zipFile->getAllInfo();
echo "<pre>";
$iterator = new \ArrayIterator($zipAllInfo);
while ($iterator->valid())
{
    $entryName = $iterator->key(); // ชื่อ path ไฟล์ หรือ โฟลเดอร์
    $zipInfo = $iterator->current(); // ข้อมูลแต่ละรายการ
	echo $zipInfo->getName(); // ชื่อไฟล์ หรือโฟลเดอร์

    $iterator->next();
}
 
 
 

    คำสั่งสำหรับจัดการไฟล์ในไฟล์ zip

    rename()
    ใช้สำหรับเปลี่ยนชื่อรายการไฟล์ในไฟล์ zip ที่เปิดใช้งานอยู่ คำสั่งเปลี่ยนชื่อจะมีผลเมื่อเราบันทึกการเปลี่ยนแปลง
หากเปลี่ยนชื่อ พร้อมระบุ path ที่ไม่มีมาก่อน จะเป็นการสร้างโฟลเดอร์เพิ่ม พร้อมย้ายไฟล์มาไว้ที่โฟลเดอร์ที่กำหนด
 
$zipFile->openFile('images.zip');
$zipFile
	->openFile($outputFilename) // open archive from file
	->rename("images/pic.png", "images/new-pic.png")
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); // close archive	
 
 
    setCompressionLevel()
    ใช้สำหรับกำหนดระดับการบีบอัดไฟล์ จะอยู่ในช่วงค่า 1 - 9 ค่าเริ่มต้นหากไม่กำหนด จะอยู่ที่ระดับ 5 เป็นค่าหลัก
แต่หากต้องการเป็นค่าอื่นก็เลือกกำหนดได้ตามต้องการ ระดับยิ่งน้อย ความเร็วในกาารบีดอัดก็จะเร็วที่สุด และค่อยๆ
ลดลงตามระดับการบีบอัด แต่คุณภาพการบีบอัดก็ยิ่งสูงตามระดับการบีบอัด โดยตัวแปรค่าคงที่หลักๆ ที่ใช้กำหนด 
จะมีด้วยกัน 4 ค่าคือ 
    SUPER_FAST = 1  FAST = 2  NORMAL = 5  MAXIMUM = 9
 
$outputFilename = "test.zip";
$zipFile
	->addDirRecursive("images")
	->setCompressionLevel(\PhpZip\Constants\ZipCompressionLevel::SUPER_FAST)
	->saveAsFile($outputFilename) //// บันทึกไฟล์ zip
	->close(); // close archive	
 
 
    setCompressionLevelEntry()
    ใช้สำหรับกำหนดระดับการบีบอัดไฟล์ ที่จะเลือกชื่อไฟล์ที่ต้องการได้ ทำงานคล้ายคำสั่ง setCompressionLevel()
เพียงแต่ แบบ setCompressionLevel() จะจัดการไฟล์ทั้งหมด ในขณะที่คำสั่งนี้จัดการเฉพาะไฟล์ที่กำหนด
 
$outputFilename = "test.zip";
$entryName = "data.doc";
$zipFile
	->addDirRecursive("images")
	->setCompressionLevelEntry($entryName, \PhpZip\Constants\ZipCompressionLevel::SUPER_FAST)
	->saveAsFile($outputFilename) //// บันทึกไฟล์ zip
	->close(); // close archive
 
 
    setCompressionMethodEntry()
    ใช้สำหรับกำหนดวิธีการบีบอัดไฟล์ ให้รายการที่ต้องการหรือกำหนด
 
$outputFilename = "test.zip";
$entryName = "data.doc";
$zipFile
	->addDirRecursive("images")
	->setCompressionMethodEntry($entryName, \PhpZip\Constants\ZipCompressionMethod::DEFLATED)
	->saveAsFile($outputFilename) //// บันทึกไฟล์ zip
	->close(); // close archive
 
 
    matcher()
    เป็นคำสั่งที่ให้เราสามารถกำหนดการเลือกรายการในไฟล์ zip ตามต้องการได้ ไม่ว่าจะเป็นการเลือกแบบเพิ่มทีละไฟล์
การเลือกแบบกำหนดรูปแบบ RegEx ให้กับชื่อไฟล์ ที่ตรงกับต้องการ หรือการเลือกไฟล์ทั้งหมด จากนั้นจัดการกับไฟล์ที่เลือก
แต่ละรายการตามลำดับ ทำให้สะดวกในการจัดการแต่ละไฟล์ต่อเนื่องได้ง่าย
 
$outputFilename = "images.zip";
$zipFile
	->openFile($outputFilename); // open archive from file
$matcher = $zipFile->matcher();
$matcher->all(); // เลือกไฟล์ทั้งหมด
$count = $matcher->count();
echo $count;// แสดงจำนวนรายการทั้งหมด
 
    การเลือกไฟล์ หรือโฟลเดอร์ เพิ่มทีละรายการ
 
$matcher
    ->add("images/subimages/sky.png")
    ->add("images/subimages/");
 
    การเลือกไฟล์ และโฟลเดอร์กำหนดแบบ array
 
$matcher->add([
	"images/subimages/sky.png",
	"images/subimages/"
]);
 
    การเลือกไฟล์ แบบใช้งานรูปแบบ RegEx
 
$matcher->match('~\.jpe?g$~i'); // เอาเฉพาะไฟล์นามสกุล jpg หรือ jpeg
$entries = $matcher->getMatches(); // มักใช้กับคำสั่งนี้ เพื่อแสดง path ชื่อไฟล์ ที่ตรงกับรูปแบบ
print_r($entries);
 
    หากต้องการวนลูปจัดการกับไฟล์แต่ละไฟล์ ให้ใช้คำสั่ง invoke() เพื่อเรียกฟังก์ชั่นการทำงานให้กับแต่ละรูป
 
// ต้วอย่างเช่นการเปลี่ยนไฟล์หลายรายการพร้อมกัน
$matcher->invoke(static function($entryName) use($zipFile) {
    $newName = preg_replace('~\.(jpe?g)$~i', '.no_optimize.$1', $entryName);
    $zipFile->rename($entryName, $newName);
});
// ต้องบันทึกเป็นไฟล์ จึงจะเห็นผลลัพธ์
$zipFile->saveAsFile($outputFilename) //// บันทึกไฟล์ zip
	->close(); // close archive	
 
    สามารถใช้คำสั่งลบไฟล์ เพื่อลบรายการที่ตรงตามรูปแบบได้ในครั้งเดียว
 
$matcher->match('~\.jpe?g$~i');
$matcher->delete(); // ลบไฟล์
// ต้องบันทึกเป็นไฟล์ จึงจะเห็นผลลัพธ์
$zipFile->saveAsFile($outputFilename) //// บันทึกไฟล์ zip
	->close(); // close archive	
 
 
 

    คำสั่งสำหรับ ลบไฟล์ใน zip ไฟล์

    deleteFromName()
    ใช้สำหรับลบไฟล์ในไฟล์ zip เพียงระบุ path และชื่อไฟล์ ที่ต้องการลบ เมื่อบันทึกการเปลี่ยนแปลง ไฟล์
zip หลังจากบันทึก จะไม่มีไฟล์ที่ลบไปแล้ว
 
$zipFile->openFile('images.zip');
$zipFile
	->openFile($outputFilename) // เปิดไฟล์ zip
	->deleteFromName("images/pass.txt") // ระบุ path ไฟล์ที่จะลบ
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); 
 
 
    deleteFromGlob()
    ลบไฟล์โดยกำหนดชนิดของไฟล์ข้อมูลที่ต้องการลบ
 
$zipFile->openFile('images.zip');
$globPattern = '**.{jpg,jpeg,png,gif}'; 
$zipFile
	->openFile($outputFilename) // เปิดไฟล์ zip
	->deleteFromGlob($globPattern) // ระบุตัวแปรชนิดไฟล์ที่จะลบ
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); 
 
 
    deleteFromRegex()
    ลบไฟล์โดยกำหนดรูปแบบชื่อไฟล์ที่สอดคล้องกับ RegEx ที่กำหนด
 
$zipFile->openFile('images.zip');
$regexPattern = '/\.(jpe?g|png|gif)$/si';
$zipFile
	->openFile($outputFilename) // เปิดไฟล์ zip
	->deleteFromRegex($regexPattern) // ระบุตัวแปรรูปแบบ RexEx ที่จะใช้
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); 
 
 
    deleteAll()
    สำหรับลบไฟล์ทั้งหมดในไฟล์ zip 
 
$zipFile->openFile('images.zip');
$zipFile
	->openFile($outputFilename) // เปิดไฟล์ zip
	->deleteAll() // ลบไฟล์ทั้งหมดในไฟล์ zip
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); 
 
 
 

    คำสั่งการเพิ่มไฟล์ และสร้างไฟล์ zip

    addFile()
    ใช้สำหรับเพิ่มไฟล์เข้าไปใน zip ไฟล์ที่จะสร้าง 
 
// แบบไม่เปลี่ยนชื่อใหม่
$file = '...../file.ext'; // path ไฟล์ที่จะเพิ่ม
addFile($file)

// แบบเปลี่ยนชื่อเป็นชื่อใหม่
$file = '...../file.ext'; 
$entryName = 'file2.ext'; // ซื่อไฟล์ใหม่ในไฟล์ zip
addFile($file, $entryName)

// สามารถเลือกรูปแบบการบีบอัดไฟล์ ใน parameter ที่ 3 ได้ ใน 3 รูปแบบคือ 
// No compression
addFile($file, $entryName, \PhpZip\Constants\ZipCompressionMethod::STORED)
// Deflate compression
addFile($file, $entryName, \PhpZip\Constants\ZipCompressionMethod::DEFLATED)
// BZIP2 compression
addFile($file, $entryName, \PhpZip\Constants\ZipCompressionMethod::BZIP2)
 
 
    addFromString()
    สำหรับสร้างไฟล์ที่จะเพิ่มเข้าไปในไฟล์ zip จาก เนื้อหาข้อมูล หรือ content ต้องการ
ตัวแปร $contents จะเป็นข้อมูลใดๆ ที่มีโครงสร้างและรูปแบบเป็น string เช่น xml json text เป็นต้น
 
$entryName = "simple.txt"; // ชื่อไฟล์ที่จะสร้างและเก็บไว้ในไฟล์ zip
// ตัวแปรข้อมูล ใช้แบบ heredoc string
$contents = <<<TXT
This is simple text file.
TXT; 
addFromString($entryName, $contents)

// สามารถเลือกรูปแบบการบีบอัดไฟล์ ใน parameter ที่ 3 ได้ ใน 3 รูปแบบคือ 
// No compression
addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::STORED)
// Deflate compression
addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::DEFLATED)
// BZIP2 compression
addFromString($entryName, $contents, \PhpZip\Constants\ZipCompressionMethod::BZIP2)

// เราสามารถอ่านข้อมูลจาก url หรือไฟล์ ด้วยคำสั่ง file_get_contents() เพื่อสร้างไฟล์ได้
// แต่จะเหมาะกับไฟล์ที่มีขนาดไม่ใหญ่เกินไป เพราะถ้าไฟล์มีขนาดใหญ่ จะทำให้ใช้หน่วยความจำมากตามไปด้วย
// เพราะเป็นการโหลดทั้งไฟล์ไปไว้ในหน่วยความจำ
$entryName = "simple.gif"; // ชื่อไฟล์ที่จะสร้างและเก็บไว้ในไฟล์ zip
// ตัวแปรข้อมูล ใช้แบบ heredoc string
$contents = file_get_contents("https://www.ninenik.com/images/logo_01_Fri.gif");
addFromString($entryName, $contents)
 
 
    addFromStream()
    สำหรับสร้างไฟล์ที่จะเพิ่มเข้าไปในไฟล์ zip จากข้อมูล stream เหมาะสำหรับใช้กับไฟล์ที่มีขนาดใหญ่ เพราะข้อมูล
จะอ่านหรือส่งมาเป็นส่วนๆ หรือเข้าใจในลักษณะกระแสข้อมูล ดึงนั้นจึงไม่ใช้หน่วยความจำเหมือนการโหลดด้วยคำสั่ง
file_get_contents() โดยข้อมูล stream จะใช้คำสั่ง fopen() ปัจจุบันจะใช้ได้เฉพาะใน domain เดียวกัน หรือภายใน
โฮสเท่านั้น ด้วยเหตุผลเรื่องความปลอดภัย 
 
$entryName = "simple.png";
$stream = fopen('mypicture.png', 'rb'); // อ่านไฟล์แบบ binary
addFromStream($stream, $entryName)

// สามารถเลือกรูปแบบการบีบอัดไฟล์ ใน parameter ที่ 3 ได้ ใน 3 รูปแบบคือ (เหมือนแนวทางด้านบน)
addFromStream($stream, $entryName, \PhpZip\Constants\ZipCompressionMethod::STORED)
addFromStream($stream, $entryName, \PhpZip\Constants\ZipCompressionMethod::DEFLATED)
addFromStream($stream, $entryName, \PhpZip\Constants\ZipCompressionMethod::BZIP2)
 
 
    addEmptyDir()
    สำหรับสร้างโฟลเดอร์ว่าง ที่จะเพิ่มเข้าไปในไฟล์ zip
 
// จะมีโฟลเดอร์ชื่อ folder ซ้อนด้วย subfolder ที่เป็นโฟลเดอร์ว่าง อยู่ด้านใน
$path = "folder/subfolder";
addEmptyDir($path)
 
 
    addAll()
    เราสามารถใช้รูปแบบต่างๆ ของการเพิ่มไฟล์เข้าไปในไฟล์ zip ที่อธิบายไปแล้วก่อนหน้า มากำหนดเป็นแบบ
array แล้วเพิ่มไปพร้อมกันได้ดังนี้
 
$contents = <<<TXT
This is simple text file.
TXT;
$stream = fopen('mypic.png', 'rb');
$path = "folder/subfolder";
$entries = [
	"demo-new.php" => "demo.php",
	"simple.txt" => $contents,
	"simple.png" => $stream,
	$path => NULL
];
$zipFile->addAll($entries);	
 
    ข้อสังเกต คำสั่งนี้ จะไม่สามารถเรียกใช้แบบ chain method ร่วมกับคำสั่ง saveAsFile() ดังนั้น เราต้องเรียก
ใช้งานแยกกันในลักษณะนี้
 
$zipFile->addAll($entries);		
$zipFile->saveAsFile($outputFilename) // save the archive to a file
        ->close(); // close archive
 
 
    addDir()
    addDirRecursive()
    คำสั่งทั้งสอง ทำงานในลักษณะเดียวกัน คือเลือกไฟล์ทั้งหมดจากโฟลเดอร์ที่กำหนด เพื่้อเพิ่มไปยังไฟล์ zip
จะแตกต่างตรงที่แบบ addDirRecursive() จะไล่ไฟล์และโฟลเดอร์ทั้งหมดหากมีโฟลเดอร์ย่อยอยู่ด้านในด้วย คำสั่งนี้
มีประโยชน์มากหากเราใช้งานกับโฟลเดอร์ที่จัดเก็บข้อมูลทั้งหมดที่เกี่ยวข้องไว้ในที่เดียวกัน เช่น รูปสินค้า ทั้งหมดเก็บ
ไว้ในโฟลเดอร์ product123 เราสามารถสร้าง zip ไฟล์ข้อมูลรูปทั้งหมด ได้ง่ายๆ เพียงแค่ระบุชื่อโฟลเดอร์ที่ต้องการ
 
$path = "path/folder"; // ระบุโฟลเดอร์ที่จะเพิ่มไฟล์ทั้งหมดในไฟล์ zip
addDir($path)	
// addDirRecursive($path)	

// เราสามารถระบุตำแหน่งของโฟลเดอร์ที่จะเก็บในไฟล์ zip ตามต้องการได้
$path = "path/folder"; // ระบุโฟลเดอร์ที่จะเพิ่มไฟล์ทั้งหมดในไฟล์ zip
$inzipPath = "to/path/folder"; // ระบุโฟลเดอร์หรือตำแหน่งที่จะเก็บในไฟล์ zip
addDir($path, $inzipPath)
// addDirRecursive($path, $inzipPath)

// สามารถเลือกรูปแบบการบีบอัดไฟล์ ใน parameter ที่ 3 ได้ ใน 3 รูปแบบคือ (เหมือนแนวทางด้านบน)
addDir($path, $inzipPath, \PhpZip\Constants\ZipCompressionMethod::STORED)
addDir($path, $inzipPath, \PhpZip\Constants\ZipCompressionMethod::DEFLATED)
addDir($path, $inzipPath, \PhpZip\Constants\ZipCompressionMethod::BZIP2)
 
 
    addFilesFromIterator()
    ทำงานคล้ายคำสั่ง addDir() และ addDirRecursive() แต่จะมีความพิเศษที่เราสามารถเลือกที่จะไม่เอาไฟล์
หรือโฟลเดอร์ที่ไม่ต้องการเพิ่มในไฟล์ zip ได้
 
// กรณีทำงานคล้าย addDir() จะใช้การกำหนดโฟลเดอร์ด้วยคำสั่ง
$dir = "images";
$directoryIterator = new \DirectoryIterator($dir); // ไม่วนเอาโฟลเดอร์ย่อย

// กรณีทำงานคล้าย addDirRecursive() จะใช้การกำหนดโฟลเดอร์ด้วยคำสั่ง
$dir = "images";
$directoryIterator = new \RecursiveDirectoryIterator($dir); // วนเอาโฟลเดอร์ย่อยและไฟล์ย่อยด้านใน ถ้ามี

// เมื่อกำหนดรูปแบบโฟลเดอร์เรียบร้อยแล้ว ก็เรียกใช้งานคำสั่ง
addFilesFromIterator($directoryIterator);
 
    ถ้าไม่ต้องการไฟล์ หรือโฟลเดอร์ใดๆ สามารถกำหนดส่วนของไฟล์หรือโฟลเดอร์ที่ไม่ต้องการแบบนี้ได้
    แบบวนในโฟลเดอร์ย่อย
 
$dir = "images";
$directoryIterator = new \RecursiveDirectoryIterator($dir); 
$ignoreFiles = [
    'file_ignore.txt',  // ไฟล์ที่ไม่เอา
    'images/subimages/' // โฟลเดอร์ที่ไม่เอา
];
$ignoreIterator = new \PhpZip\Util\Iterator\IgnoreFilesRecursiveFilterIterator(
    $directoryIterator, 
    $ignoreFiles
);
addFilesFromIterator($ignoreIterator);
 
    แบบไม่วนในโฟลเดอร์ย่อย
 
$dir = "images";
$directoryIterator = new \RecursiveDirectoryIterator($dir); 
$ignoreFiles = [
    'file_ignore.txt',  // ไฟล์ที่ไม่เอา
];
$ignoreIterator = new \PhpZip\Util\Iterator\IgnoreFilesFilterIterator(
    $directoryIterator, 
    $ignoreFiles
);
addFilesFromIterator($ignoreIterator);
 
    รองรับการกำหนด parameter ที่ 2 และ 3 เช่นด้วยกับคำสั่ง addDir() และ addDirRecursive() 
 
 
    addFilesFromGlob()
    addFilesFromGlobRecursive()
    สองคำสั่งนี้ เหมือนเพิ่มความสามารถให้กับคำสั่ง addDir() และ addDirRecursive() โดยทำงานคล้ายกัน เพียง
แต่เพิ่มส่วนของการเลือกชนิดของไฟล์ที่ต้องการ โดยระบุนามสกุลไฟล์ ที่ต้องการเพิ่มไปในไฟล์ zip 
 
// สมมติต้องการเฉพาะไฟล์รูปภาพ ตามสกุลไฟล์ที่ระบุดังนี้
$globPattern = '**.{jpg,jpeg,png,gif}';

$dir = "images";
addFilesFromGlobRecursive($dir, $globPattern);
// addFilesFromGlob($dir, $globPattern); // แบบไม่รวมโฟลเดอร์ย่อย
 
    เนื่องจากคำสั่งนี้มี parameter เพิ่มเข้ามา ดังนั้น เราสามารถกำหนด paramter ที่ระบุ path ที่จะเก็บในไฟล์ zip
และกำหนด วิธีการบีบอัดไฟล์ เป็น parameter ที่ 3 และ 4 แทนตามลำดับ
 
$inzipPath = "to/path/folder"; // ระบุโฟลเดอร์หรือตำแหน่งที่จะเก็บในไฟล์ zip
addFilesFromGlobRecursive($dir, $globPattern, $inzipPath);

// แบบกำหนดวิธีการบีดอัด
addFilesFromGlobRecursive($dir, $globPattern, $inzipPath, \PhpZip\Constants\ZipCompressionMethod::STORED);
 
 
    addFilesFromRegex()
    addFilesFromRegexRecursive()
    สองคำสั่งนี้ เหมือนเพิ่มความสามารถให้กับคำสั่ง addDir() และ addDirRecursive() โดยทำงานคล้ายกัน เพียง
แต่เพิ่มส่วนของการเลือกชนิดของไฟล์ที่ต้องการ โดยระบุการเลือกไฟล์ผ่านชื่อที่ตรงกับรูปแบบ RegEx ที่กำหนด
เพื่อเพิ่มไปในไฟล์ zip 
 
// สมมติต้องการเฉพาะไฟล์รูปภาพ ตามสกุลไฟล์ที่ระบุดังนี้
$regexPattern = '/\.(jpe?g|png|gif)$/si';

$dir = "images";
addFilesFromRegexRecursive($dir, $regexPattern);
// addFilesFromRegex($dir, $regexPattern); // แบบไม่รวมโฟลเดอร์ย่อย
 
    เนื่องจากคำสั่งนี้มี parameter เพิ่มเข้ามา ดังนั้น เราสามารถกำหนด paramter ที่ระบุ path ที่จะเก็บในไฟล์ zip
และกำหนด วิธีการบีบอัดไฟล์ เป็น parameter ที่ 3 และ 4 แทนตามลำดับ
 
$inzipPath = "to/path/folder"; // ระบุโฟลเดอร์หรือตำแหน่งที่จะเก็บในไฟล์ zip
addFilesFromRegexRecursive($dir, $regexPattern, $inzipPath);

// แบบกำหนดวิธีการบีดอัด
addFilesFromRegexRecursive($dir, $regexPattern, $inzipPath, \PhpZip\Constants\ZipCompressionMethod::STORED);
 
 
 

    คำสั่งบันทึกและแสดงข้อมูลไฟล์ zip

    saveAsFile()
    เป็นคำสั่งที่เราเรียกใช้งานหลังจากเพิ่มข้อมูล หรือไฟล์ต่างๆ ที่จะสร้างเป็นไฟล์ zip แล้ว  เราก็ต้องกำหนดชื่อไฟล์
zip ที่ต้องการ และบันทึกข้อมูลไว้ในไฟล์นี้ รูปแบบการใช้งานก็ง่ายๆ เพียงแค่กำหนด path และชื่อไฟล์ zip ที่ต้องการ
อย่าลืมว่า path หรือโฟลเดอร์ที่จะทำการบันทึกไฟล์ ต้องสามารถเขียนไฟล์ได้ หรือเปิด permission เป็น 755 หรือ 777
 
$outputFilename = "test.zip";
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->saveAsFile($outputFilename) // บันทึก zip ไฟล์
	->close(); // close archive
 
 
    saveAsStream()
    เป็นคำสั่งสำหรับไฟล์ zip แบบข้อมูล stream เหมาะกับไฟล์ zip ที่มีจำนวนหรือขนาดไฟล์รวมกันจำนวนมาก หรือมี
ขนาดไฟล์ที่ใหญ่  เนื่องจากรูปแบบการบันทึกแบบ stream จะเป็นการบันทึกข้อมูลทีละส่วน เป็นกระแสข้อมูล ทำให้หาก
ทำงานกับไฟล์จำนวนมากๆ จะไม่มีปัญหาเรื่องการใช้งานหน่วยความจำ
    คำสั่งนี้ใช้งานร่วมกับคำสั่ง fopen() สำหรับเขียนข้อมูลไฟล์
 
$outputFilename = "text.zip";
$fp = fopen($outputFilename, 'w+b');
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->saveAsStream($fp) // บันทึก zip ไฟล์
	->close(); // close archive
 
 
    outputAsString()
    สำหรับคืนค่าข้อมูลไฟล์ zip ที่จะสร้างเป็นข้อมูล string  เราสามารถนำไปใช้งานต่อ เช่น บันทึกลงฐานข้อมูล หรือ
นำไปจัดการต่อด้วยคำสั่ง openFromString() ที่อธิบายไปก่อนหน้าได้
 
$zipFile->addDir(__DIR__); // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
$rawZipArchiveBytes = $zipFile->outputAsString(); // กำหนด string ข้อมูลไฟล์ zip ในตัวแปร ไว้ใช้งาน
 
 
    outputAsAttachment()
    สำหรับสร้างไฟล์ zip ได้ไม่ต้องบันทึกเป็นไฟล์ไว้ในบน server แต่ให้สามารถดาวน์โหลด เป็นไฟล์ลงมาที่เครื่อง
ได้ทันที
 
$outputFilename = "text.zip";
// $mimeType = 'application/zip'; // สามารถกำหนด mimetype
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->outputAsAttachment($outputFilename) // ดาวน์โหลดไฟล์ zip
//	->outputAsAttachment($outputFilename, $mimeType) // แบบกำหนด mimetype
	->close(); // close archive
 
 
 

    คำสั่งตั้งค่า จัดการรหัสผ่านไฟล์ zip

    setReadPassword()
    ใช้สำหรับเปิดไฟล์ zip ที่ติดรหัสผ่าน ยกเว้นกรณีการเพิ่มไฟล์ใหม่ หรือการลบไฟล์ในไฟล์ zip ไม่ต้องเรียกใช้
คำสั่งนี้ ใช้คำสั่งนี้ กรณีเปิดไฟล์ zip เพื่อแตกไฟล์ หรือเปลี่ยนแปลงรูปแบบการบีบอัดไฟล์ เปลี่ยน level การบีบอัดไฟล์
เปลี่ยนรูปแบบการเข้ารหัส หรือเปลี่ยนรหัสผ่านไฟล์ zip ใหม่ จะต้องใช้คำสั่ง
 
$outputFilename = "images.zip";
$zipFile
	->openFile($outputFilename) // เปิดไฟล์ zip
	->setReadPassword("123456") // รหัสผ่าน สำหรับเปิพไฟล์ ที่มีการตั้งรหัสผ่าน
	->extractTo("./temp"); // แตกไฟล์ zip ไปโฟลเดอร์ temp
 
 
    setPassword()
    ใช้สำหรับตั้งรหัสผ่านให้กับไฟล์ zip ที่เราสร้างหรือแก้ไข หรือเปลี่ยนรหัสผ่านใหม่ เราสามาถกำหนดรูปแบบการเข้ารหัส
ได้ โดยเลือกรูปแบบได้ดังนี้
 
\PhpZip\Constants\ZipEncryptionMethod::PKWARE - Traditional PKWARE encryption (แบบเก่า)
\PhpZip\Constants\ZipEncryptionMethod::WINZIP_AES_256 - WinZip AES encryption 256 bit (วิธีที่แนะนำ)
\PhpZip\Constants\ZipEncryptionMethod::WINZIP_AES_192 - WinZip AES encryption 192 bit
\PhpZip\Constants\ZipEncryptionMethod::WINZIP_AES_128 - WinZip AES encryption 128 bit
 
    ดูตัวอย่างการกำหนดรหัสผ่าน
 
$outputFilename = "text.zip";
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->setPassword("123456") // ตั้งรหัสผ่านตามต้องการ
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); // close archive
 
    แบบกำหนดรูปแบบการเข้ารหัส
 
$outputFilename = "text.zip";
$encryptionMethod = \PhpZip\Constants\ZipEncryptionMethod::WINZIP_AES_256;
$zipFile
	->addDir(__DIR__) // เพิ่มไฟล์จาก โฟลเดอร์ปัจจุบัน ของไฟล์ทดสอบนี้
	->setPassword("123456", $encryptionMethod) // ตั้งรหัสผ่านตามต้องการ
	->saveAsFile($outputFilename) // บันทึกไฟล์ zip
	->close(); // close archive	
 
 
    เนื้อหานี้เสมือนเป็นคู่มือรายละเอียด และแนวทางการใช้งานเพิ่มเติม สามารถนำไปปรับใช้ตามต้องการ


กด Like หรือ Share เป็นกำลังใจ ให้มีบทความใหม่ๆ เรื่อยๆ น่ะครับ











URL สำหรับอ้างอิง











เว็บไซต์ของเราให้บริการเนื้อหาบทความสำหรับนักพัฒนา โดยพึ่งพารายได้เล็กน้อยจากการแสดงโฆษณา โปรดสนับสนุนเว็บไซต์ของเราด้วยการปิดการใช้งานตัวปิดกั้นโฆษณา (Disable Ads Blocker) ขอบคุณครับ