เนื้อหานี้จะมาแนะนำการใช้งาน 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
เนื้อหานี้เสมือนเป็นคู่มือรายละเอียด และแนวทางการใช้งานเพิ่มเติม สามารถนำไปปรับใช้ตามต้องการ