對某些人來說可能有點明顯,但這是我疏忽之處。
如果您要將檔案新增到您想要刪除的 zip 檔案中,請確保在呼叫 close() 函數後才刪除。
如果新增到物件的檔案在儲存時不可用,則不會建立 zip 檔案。
(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL zip >= 1.1.0)
ZipArchive::close — 關閉作用中的封存檔(已開啟或新建立的)
關閉已開啟或已建立的封存檔,並儲存變更。此方法會在腳本結束時自動呼叫。
如果封存檔不包含任何檔案,則根據 ZipArchive::AFL_CREATE_OR_KEEP_FILE_FOR_EMPTY_ARCHIVE
全域旗標的值,預設會完全移除檔案(不會寫入空的封存檔)。
此函數沒有任何參數。
對某些人來說可能有點明顯,但這是我疏忽之處。
如果您要將檔案新增到您想要刪除的 zip 檔案中,請確保在呼叫 close() 函數後才刪除。
如果新增到物件的檔案在儲存時不可用,則不會建立 zip 檔案。
如果您要將多個檔案新增到一個 zip 檔,而且您的 $zip->close() 呼叫傳回 FALSE,請確保您新增的所有檔案都實際存在。顯然,即使檔案實際不存在,$zip->addFile() 也會傳回 TRUE。在呼叫 $zip->addFile() 之前,最好使用 file_exists() 或 is_readable() 檢查每個檔案。
ZipArchive.close() 在 PHP7 中的行為有所改變。該函數在 PHP5 中會忽略目錄,但在 PHP7 中會失敗,並顯示
Unexpected PHP error [ZipArchive::close(): 讀取錯誤:是一個目錄]
以下程式碼在 PHP5 中可運作,但在 PHP7 中則不行
<?php
// test.php
$zip = new ZipArchive();
$zip->open('/tmp/test.zip', ZipArchive::CREATE);
$zip->addFile('.', '.');
$ret = $zip->close();
echo "關閉時為: " . ($ret ? "true" : "false") . "\n";
?>
適用於 php5
php --version
PHP 5.5.38-1-avature-ondrej-fork (cli) (built: Aug 31 2016 16:37:38)
php test.php
關閉時為: true
適用於 php7
php --version
PHP 7.0.8-0ubuntu0.16.04.2 (cli) ( NTS )
php test.php
關閉時為: false
如果您建立了一個 zip 檔案並在其中新增了一個檔案而沒有錯誤,但 ZipArchive::close 呼叫失敗(出現 ER_TMPOPEN:"無法建立暫存檔")且未建立 zip 檔案,請檢查您的 ZipArchive::open 呼叫是否指定了包含不存在目錄的路徑名稱。如果您預期有一個或多個目錄的包含階層,則必須在使用 ZipArchive 之前自行建立它們。您可以編寫一個簡單的函數,使用 dirname 遞迴尋找每個父目錄,並在離開遞迴時使用 mkdir 建立不存在的目錄。
我不確定,但如果 $zip->open 中指定的路徑是相對路徑而不是絕對路徑,則 $zip->close() 似乎可能會發生錯誤。
因此,當建立封存檔時,請為要建立的 zip 檔案指定絕對路徑,而不是相對路徑。
別忘了檢查 zip 檔是否為空的,各位 - 否則根本不會建立 zip 檔,而且伺服器不會發出任何警告!
我使用某個迴圈將檔案新增到 zip 檔中,並為權限和文件奮鬥了好幾個小時,才意識到迴圈最終沒有新增任何檔案,即使 addFile 有被呼叫,但卻是在一個不存在的檔案上呼叫。
這可能是您的 zip 檔沒有彈出的原因。
請注意,ZipArchive::addFile() 僅開啟檔案描述符,而不壓縮它。只有 ZipArchive::close() 會壓縮檔案,而且需要相當長的時間。請小心逾時。