请注意,'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 "The files don't match!";
}
?>