本篇文章更新時間:2022/10/08
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
標題感覺籠統,實際上這種使用案例還滿常見,像是 WordPress 有些子主題產生站,只要輸入想要的子主題名字,他就會自動生成一個主題檔案,並提供下載一個「子主題.zip」這樣的功能。
類似的應用不少,概念上就是前端讓人輸入一些變數的值,後端收到後將這些變數帶入系統運作的邏輯中,將數個檔案寫入 Zip 壓縮檔案後,讓使用者下載這個客製化的打包檔案。
最近剛好有這需求,節錄關鍵程式如下:
$res = $zip->open($zip_full_path, ZipArchive::CREATE);
if ($res !== TRUE) {
exit('ERROR_EXECUTE');
}
foreach (glob_recursive($zip_folder, "*") as $key => $entry) {
$f = pathinfo(strtolower($entry));
if ($entry != "." && $entry != ".." && !in_array($f['extension'], array('php')) && $f['filename'] != "" && strpos($f['basename'], '.') !== 0) {
$new_path_in_zip = str_replace(dirname(__FILE__) . '/path', '', $entry);
if (is_dir($entry)) {
$zip->addEmptyDir($entry, $new_path_in_zip);
} else {
if ($new_path_in_zip == '/special_' . $type . '/data/blah_' . $type . '.txt') {
$zip->addFromString($new_path_in_zip, $user_input);
} else {
$zip->addFile($entry, $new_path_in_zip);
}
}
}
}
$zip->close();
$download_name = "My_Awesome.zip";
header('Pragma: no-cache');
header('Expires: 0');
header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=" . $download_name);
header('Content-Length: ' . filesize($zip_full_path));
header("Pragma: no-cache");
header("Expires: 0");
@readfile($zip_full_path);
這隻程式會掃描預設樣板的資料夾,並且 1:1 的加入壓縮檔案中,唯獨針對要替換的部分使用 addFromString
來輸入。
要注意的是產生這個 Zip 檔案要亂數命名,避免太多人執行的時候導致開檔讀檔的 IO 問題。
原本以為把檔案都 addFile
去加入壓縮檔就好,但因為我的樣板目錄本身也包含其他子目錄,所以還要記得也去建立 Zip 檔案裡的目錄 addEmptyDir
。
更多使用案例這篇文章 How To Add Files & Folders In PHP ZIP – Basics, Entire Folder, Recursive 介紹的很詳細!
反倒是 PHP 文件裡沒找到太多資料。下面方法重點筆記:
$zip->open() //建立 Zip 檔案
$zip->addEmptyDir() //建立 Zip 中空目錄
$zip->addFile() //新增檔案
$zip->addFromString() //從字串去新增檔案
$zip->addGlob() //掃描目錄新增檔案
$zip->addPattern() //透過設定模式新增
$zip->close() //都處理完後要關閉 Zip 檔案