php_zip_archive_file_num_incorrect

PHP ZipArchive 壓縮檔案數量不正確

問題

上傳了一個縮檔檔 (file.zip),內包含兩個圖片

使用程式碼解壓縮,逐一上傳到伺服器

1
2
3
4
$zip = new \ZipArchive();
for ($i = 0; $i < $zip->numFiles; $i++) {
// 上傳檔案
}

但發現 $zip->numFiles 的數量不正確,有四個檔案

查詢所有的$ file_name,發現有兩個檔案是 __MACOSX/._ 開頭的檔案

1
2
3
4
$zip = new \ZipArchive();
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
}
1
2
3
4
local.INFO: stat [{"name":"pic1.jpg","index":0,"crc":386404580,"size":42992,"mtime":1714363176,"comp_size":38074,"comp_method":8,"encryption_method":0}]
local.INFO: stat [{"name":"__MACOSX/.pic1.jpg","index":1,"crc":44379887,"size":340,"mtime":1714363176,"comp_size":197,"comp_method":8,"encryption_method":0}]
local.INFO: stat [{"name":"pic2.jpg","index":2,"crc":1810608204,"size":13140,"mtime":1714361602,"comp_size":9669,"comp_method":8,"encryption_method":0}]
local.INFO: stat [{"name":"__MACOSX/.pic2.jpg","index":3,"crc":2480374228,"size":340,"mtime":1714361602,"comp_size":214,"comp_method":8,"encryption_method":0}]

__MACOSX/ 是一個在 macOS 系統中創建的 zip 檔案可能會包含的特殊目錄。當你在 macOS 中使用內建的壓縮工具來創建 zip 檔案時,系統會自動在 zip 檔案中創建一個名為 __MACOSX/ 的目錄。

解決方法

判斷開頭為 __MACOSX/._ 的檔案,不進行上傳

1
2
3
4
5
6
7
8
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
if (strpos($entry, '__MACOSX/') === 0) {
// This is a __MACOSX/ entry, skip it
continue;
}
// 上傳檔案
}