在處理ZIP 壓縮文件時,尤其是在解壓包含多級目錄結構的壓縮包時,確保目標目錄存在是非常重要的一步。否則,寫入文件時可能會因為目標路徑不存在而導致失敗。本文將介紹如何使用zip_read()函數讀取ZIP 文件的每一個條目,並結合file_exists()和mkdir()自動創建所需目錄,從而實現穩定的文件提取過程。
確保你的PHP 環境已經啟用了zip擴展。你可以使用以下代碼檢測:
<?php
if (!class_exists('ZipArchive')) {
die('Zip 擴展未啟用');
}
?>
下面是完整的示例代碼,實現從ZIP 文件中讀取文件和目錄,並自動創建目錄結構:
<?php
$zipPath = 'example.zip'; // ZIP 文件路徑
$extractTo = 'output/'; // 解壓目錄
$zip = zip_open($zipPath);
if (!is_resource($zip)) {
die('無法打開 ZIP 文件');
}
while ($entry = zip_read($zip)) {
$entryName = zip_entry_name($entry);
$fullPath = $extractTo . $entryName;
// 獲取目錄路徑
$dir = dirname($fullPath);
// 自動創建目錄
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
// 如果是文件,就讀取內容並寫入
if (zip_entry_open($zip, $entry, "r")) {
$content = zip_entry_read($entry, zip_entry_filesize($entry));
file_put_contents($fullPath, $content);
zip_entry_close($entry);
}
}
zip_close($zip);
?>
zip_open()
用於打開ZIP 文件,返回一個資源句柄。
zip_read() 與zip_entry_name()
通過zip_read() 逐條讀取壓縮包中的條目,然後用zip_entry_name() 獲取該條目的相對路徑。
dirname() 提取目錄路徑
無論是文件還是目錄,使用dirname() 提取路徑部分,然後檢查目錄是否存在
file_exists() 與mkdir() 配合使用
file_exists() 用於判斷目錄是否已存在;
mkdir() 使用第三個參數設為true以遞歸創建多級目錄。
寫入文件內容
如果當前條目是文件,則打開、讀取並寫入到目標路徑
假設你從http://m66.net/files/archive.zip下載了一個壓縮包,解壓後希望保留其原始結構,只需要修改$zipPath即可:
$zipPath = 'http://m66.net/files/archive.zip'; // 注意:zip_open 不支持直接使用 URL,需先下載到本地
可使用file_get_contents()和file_put_contents()先將文件保存到本地:
$tempZip = 'temp_archive.zip';
file_put_contents($tempZip, file_get_contents('http://m66.net/files/archive.zip'));
然後將$zipPath替換為$tempZip即可。
通過結合zip_read() 、 file_exists()和mkdir() ,我們可以高效地實現ZIP 文件內容的自動提取與目錄創建,無需擔心路徑不存在導致的錯誤。這個方法特別適合用於批量解壓帶有復雜目錄結構的ZIP 文件,提升了腳本的健壯性和可用性。