请注意,'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 可能会作为带符号 int 出现负数。
if($newCrc !== $oldCrc && ($oldCrc + 4294967296) !== $newCrc) {
echo "文件不匹配!";
}
?>