当前位置: 首页> 最新文章列表> 如何使用 zip_read() 函数正确解压包含空目录的 Zip 文件,避免空目录丢失问题?

如何使用 zip_read() 函数正确解压包含空目录的 Zip 文件,避免空目录丢失问题?

M66 2025-07-18

在 PHP 中处理 ZIP 文件时,zip_read() 函数是读取 ZIP 文件条目的常用方法。但在解压包含空目录的 ZIP 文件时,很多开发者会遇到空目录丢失的问题。这是因为空目录本身没有文件,zip_read() 默认只遍历文件条目,而忽略了目录条目,导致空目录无法被正确创建。

本文将结合示例代码,详细介绍如何利用 zip_read() 函数正确识别和解压空目录,避免空目录丢失,保证解压后的文件结构完整。


1. 问题分析

ZIP 文件的条目既包括文件也包括目录,目录条目通常以 / 结尾。zip_read() 返回的条目名称中,如果以 / 结尾,则表示这是一个目录。普通解压时,如果只创建文件对应目录,却不处理空目录条目,空目录就会被忽略。


2. 示例代码演示

下面是一个基于 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);
?>

3. 关键点总结

  • 判断目录条目:利用 zip_entry_name() 获取条目名称,目录条目一般以 / 结尾。

  • 创建空目录:遇到目录条目,直接创建对应目录。

  • 创建文件及其父目录:对于文件条目,先确保父目录存在,再写入文件内容。

  • 权限和递归创建mkdir() 的第三个参数设置为 true,递归创建多级目录。


4. 相关链接

更多关于 PHP Zip 函数的文档,可参考官方手册: