請注意,'mtime' 欄位僅來自儲存在 zip 檔案中的 DOS 格式時間,其精度僅為最接近的 2 秒。Zip 檔案可以在多個選用欄位中儲存 mtime,但 PHP 的 zip 函式庫不會擷取它們(也不會提供存取額外欄位的 API)。
最終結果是,您會看到時間戳記可能相差一秒(如果原始時間戳記為奇數),而且不一定與其他解壓縮程式顯示的 mtime 相符。
(PHP 5 >= 5.2.0, PHP 7, PHP 8, PECL zip >= 1.1.0)
ZipArchive::statIndex — 取得由索引定義的項目的詳細資訊
返回一個包含項目詳細資訊的陣列,如果失敗則返回 false
。
範例 #1 傾印項目的統計資訊
<?php
$zip = new ZipArchive;
$res = $zip->open('test.zip');
if ($res === TRUE) {
print_r($zip->statIndex(3));
$zip->close();
} else {
echo 'failed, code:' . $res;
}
?>
上述範例將輸出類似以下的內容
Array ( [name] => foobar/baz [index] => 3 [crc] => 499465816 [size] => 27 [mtime] => 1123164748 [comp_size] => 24 [comp_method] => 8 )
請注意,'mtime' 欄位僅來自儲存在 zip 檔案中的 DOS 格式時間,其精度僅為最接近的 2 秒。Zip 檔案可以在多個選用欄位中儲存 mtime,但 PHP 的 zip 函式庫不會擷取它們(也不會提供存取額外欄位的 API)。
最終結果是,您會看到時間戳記可能相差一秒(如果原始時間戳記為奇數),而且不一定與其他解壓縮程式顯示的 mtime 相符。
請注意,帶符號整數 CRC 結果僅在 32 位元系統上為真。64 位元系統會返回正確的 CRC。
更安全的方法(如 crc32() 函式頁面所建議)可能是
if ($file['crc'] < 0)
$file['crc'] = sprintf("%u",$file['crc']);
此方法返回的 CRC 是帶符號的數字,因此可能為負數。這與大多數 CRC 的表示方式不同,因此可能會造成問題。另一件需要注意的事情是,zip 檔案使用的標準 CRC 演算法是 CRC32b。
因此,綜上所述,假設您想要從 zip 檔案中提取第一個檔案,然後比較原始 CRC 與提取檔案的 CRC,這就是您需要做的。(為了簡潔起見,省略了適當的錯誤檢查)。
<?php
$zip = new ZipArchive();
$zip->open("myZip.zip");
$stat = $zip->statIndex( 0 );
$name = $stat['name'];
$oldCrc = $stat['crc'];
$zip->extractTo("myPath", $name);
$newCrc = hexdec(hash_file("crc32b", "myPath/" . $name));
// 必須測試兩種情況,因為 zip 檔案內的無符號 CRC 作為有符號整數時可能會顯示為負數。
if($newCrc !== $oldCrc && ($oldCrc + 4294967296) !== $newCrc) {
echo "檔案不符!";
}
?>