在 PHP 中处理 ZIP 文件时,zip_read() 函数是读取 ZIP 文件条目的常用方法。但在解压包含空目录的 ZIP 文件时,很多开发者会遇到空目录丢失的问题。这是因为空目录本身没有文件,zip_read() 默认只遍历文件条目,而忽略了目录条目,导致空目录无法被正确创建。
本文将结合示例代码,详细介绍如何利用 zip_read() 函数正确识别和解压空目录,避免空目录丢失,保证解压后的文件结构完整。
ZIP 文件的条目既包括文件也包括目录,目录条目通常以 / 结尾。zip_read() 返回的条目名称中,如果以 / 结尾,则表示这是一个目录。普通解压时,如果只创建文件对应目录,却不处理空目录条目,空目录就会被忽略。
下面是一个基于 PHP 原生 ZIP 函数的示例,演示如何读取 ZIP 文件,区分文件和目录,并正确创建空目录。
<?php
$zipPath = 'archive.zip'; // ZIP 文件路径
$extractTo = 'output/'; // 解压目标目录
$zip = zip_open($zipPath);
if (!is_resource($zip)) {
die("无法打开 ZIP 文件\n");
}
while ($entry = zip_read($zip)) {
$entryName = zip_entry_name($entry);
// 判断是否目录条目,目录条目以 '/' 结尾
if (substr($entryName, -1) === '/') {
// 创建空目录
$dirPath = $extractTo . $entryName;
if (!is_dir($dirPath)) {
mkdir($dirPath, 0755, true);
echo "创建空目录:$dirPath\n";
}
} else {
// 文件条目,先确保目录存在
$filePath = $extractTo . $entryName;
$dir = dirname($filePath);
if (!is_dir($dir)) {
mkdir($dir, 0755, true);
}
// 读取文件内容并写入
if (zip_entry_open($zip, $entry)) {
$fp = fopen($filePath, 'w');
while ($data = zip_entry_read($entry, 1024)) {
fwrite($fp, $data);
}
fclose($fp);
zip_entry_close($entry);
echo "解压文件:$filePath\n";
}
}
}
zip_close($zip);
?>
判断目录条目:利用 zip_entry_name() 获取条目名称,目录条目一般以 / 结尾。
创建空目录:遇到目录条目,直接创建对应目录。
创建文件及其父目录:对于文件条目,先确保父目录存在,再写入文件内容。
权限和递归创建:mkdir() 的第三个参数设置为 true,递归创建多级目录。
更多关于 PHP Zip 函数的文档,可参考官方手册: