通用建立 ZIP 函數
<?php
/**
* 建立 ZIP 壓縮檔
* @param array $files 要壓縮的檔案路徑陣列
* @param string $destination 輸出 ZIP 路徑
* @param bool $overwrite 是否覆蓋既有檔案
* @return bool 成功 true,失敗 false
*/
function create_zip($files = [], $destination = '', $overwrite = false) {
// 檢查輸出檔案
if (file_exists($destination) && !$overwrite) {
return false;
}
// 過濾存在的檔案
$valid_files = [];
if (is_array($files)) {
foreach ($files as $file) {
if (file_exists($file)) {
$valid_files[] = $file;
}
}
}
if (empty($valid_files)) return false;
// 建立壓縮檔
$zip = new ZipArchive();
$flags = $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE;
if ($zip->open($destination, $flags) !== true) {
return false;
}
// 加入檔案 (第二參數為 ZIP 內部路徑,這裡保持原檔名)
foreach ($valid_files as $file) {
$zip->addFile($file, basename($file));
}
$zip->close();
return file_exists($destination);
}
?>
使用範例
<?php
$files_to_zip = [
'preload-images/1.jpg',
'preload-images/2.jpg',
'preload-images/5.jpg',
'kwicks/ringo.gif',
'rod.jpg',
'reddit.gif'
];
$result = create_zip($files_to_zip, 'my-archive.zip', true);
if ($result) {
echo "壓縮成功: my-archive.zip (" . filesize('my-archive.zip') . " bytes)";
} else {
echo "壓縮失敗";
}
?>
進階擴充建議
| 需求 | 實作方向 |
| 保留目錄結構 | $zip->addFile($file, $relativePath) 計算相對路徑 |
| 壓縮整個目錄 | 遞迴掃描 RecursiveDirectoryIterator 加入所有檔案 |
| 密碼保護 | ZipArchive 不支援,需用 exec('zip -e ...') 或 pclzip |
| 大檔案分卷 | ZipArchive 不支援,需外部工具 |
| 記憶體優化 | 分批寫入、臨時檔、串流壓縮 |
ZipArchive 常用方法速查
addFile($path, $localname):加入檔案
addFromString($name, $content):直接加入字串內容
addEmptyDir($dirname):加入空目錄
extractTo($destination):解壓縮
deleteIndex($index):刪除指定索引檔案
deleteName($name):刪除指定名稱檔案
getStatusString():取得錯誤狀態訊息
setCompressionIndex($index, $method):設定壓縮演算法
替代方案:PclZip (純 PHP、無需擴展)
require_once 'pclzip.lib.php';
$archive = new PclZip('archive.zip');
$list = $archive->create('file1.txt,file2.txt,folder');
if ($list === 0) die("Error: " . $archive->errorInfo(true));