在处理 ZIP 压缩文件时,尤其是在解压包含多级目录结构的压缩包时,确保目标目录存在是非常重要的一步。否则,写入文件时可能会因为目标路径不存在而导致失败。本文将介绍如何使用 zip_read() 函数读取 ZIP 文件的每一个条目,并结合 file_exists() 和 mkdir() 自动创建所需目录,从而实现稳定的文件提取过程。
确保你的 PHP 环境已经启用了 zip 扩展。你可以使用以下代码检测:
<?php
if (!class_exists('ZipArchive')) {
die('Zip 扩展未启用');
}
?>
下面是完整的示例代码,实现从 ZIP 文件中读取文件和目录,并自动创建目录结构:
<?php
$zipPath = 'example.zip'; // ZIP 文件路径
$extractTo = 'output/'; // 解压目录
$zip = zip_open($zipPath);
if (!is_resource($zip)) {
die('无法打开 ZIP 文件');
}
while ($entry = zip_read($zip)) {
$entryName = zip_entry_name($entry);
$fullPath = $extractTo . $entryName;
// 获取目录路径
$dir = dirname($fullPath);
// 自动创建目录
if (!file_exists($dir)) {
mkdir($dir, 0777, true);
}
// 如果是文件,就读取内容并写入
if (zip_entry_open($zip, $entry, "r")) {
$content = zip_entry_read($entry, zip_entry_filesize($entry));
file_put_contents($fullPath, $content);
zip_entry_close($entry);
}
}
zip_close($zip);
?>
zip_open()
用于打开 ZIP 文件,返回一个资源句柄。
zip_read() 与 zip_entry_name()
通过 zip_read() 逐条读取压缩包中的条目,然后用 zip_entry_name() 获取该条目的相对路径。
dirname() 提取目录路径
无论是文件还是目录,使用 dirname() 提取路径部分,然后检查目录是否存在。
file_exists() 与 mkdir() 配合使用
file_exists() 用于判断目录是否已存在;
mkdir() 使用第三个参数设为 true 以递归创建多级目录。
写入文件内容
如果当前条目是文件,则打开、读取并写入到目标路径。
假设你从 http://m66.net/files/archive.zip 下载了一个压缩包,解压后希望保留其原始结构,只需要修改 $zipPath 即可:
$zipPath = 'http://m66.net/files/archive.zip'; // 注意:zip_open 不支持直接使用 URL,需先下载到本地
可使用 file_get_contents() 和 file_put_contents() 先将文件保存到本地:
$tempZip = 'temp_archive.zip';
file_put_contents($tempZip, file_get_contents('http://m66.net/files/archive.zip'));
然后将 $zipPath 替换为 $tempZip 即可。
通过结合 zip_read()、file_exists() 和 mkdir(),我们可以高效地实现 ZIP 文件内容的自动提取与目录创建,无需担心路径不存在导致的错误。这个方法特别适合用于批量解压带有复杂目录结构的 ZIP 文件,提升了脚本的健壮性和可用性。