Zip 扩展
PHP 的 Zip 扩展提供了创建、读取和修改 ZIP 压缩文件的完整支持。ZIP 是最常见的归档格式之一,广泛用于文件打包、代码分发和数据备份。本节将全面讲解 PHP Zip 扩展的使用方法。
基础概念
安装
bash
# 编译安装
./configure --enable-zip
# Ubuntu/Debian
sudo apt-get install php-zip创建 ZIP 文件
基本创建
php
<?php
declare(strict_types=1);
$zip = new ZipArchive();
$filename = '/tmp/archive.zip';
if ($zip->open($filename, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
throw new RuntimeException("无法创建 ZIP 文件");
}
// 添加文件
$zip->addFile('/path/to/file.txt', 'file.txt');
$zip->addFile('/path/to/image.jpg', 'images/photo.jpg');
// 添加空目录
$zip->addEmptyDir('docs/');
// 从字符串添加文件
$zip->addFromString('config.json', json_encode(['debug' => true], JSON_PRETTY_PRINT));
// 关闭(保存)
$zip->close();
echo "ZIP 文件创建成功: {$filename}" . PHP_EOL;递归添加目录
php
<?php
declare(strict_types=1);
function zipDirectory(string $dir, string $archivePath): void
{
$zip = new ZipArchive();
if ($zip->open($archivePath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
throw new RuntimeException("无法创建 ZIP: {$archivePath}");
}
$dir = rtrim($dir, DIRECTORY_SEPARATOR);
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::SELF_FIRST
);
foreach ($iterator as $item) {
$relativePath = substr($item->getPathname(), strlen($dir) + 1);
if ($item->isDir()) {
$zip->addEmptyDir($relativePath . '/');
} else {
$zip->addFile($item->getPathname(), $relativePath);
}
}
$zip->close();
}
zipDirectory('/path/to/project', '/tmp/project.zip');读取 ZIP 文件
php
<?php
declare(strict_types=1);
$zip = new ZipArchive();
if ($zip->open('/tmp/archive.zip') !== true) {
throw new RuntimeException("无法打开 ZIP 文件");
}
// 获取文件数量和注释
echo "文件数: " . $zip->numFiles . PHP_EOL;
echo "注释: " . $zip->comment . PHP_EOL;
echo "状态: " . $zip->status . PHP_EOL;
// 遍历所有条目
for ($i = 0; $i < $zip->numFiles; $i++) {
$stat = $zip->statIndex($i);
echo " {$stat['name']} - {$stat['size']} bytes - " . date('Y-m-d', $stat['mtime']) . PHP_EOL;
}
// 获取特定文件内容
$content = $zip->getFromName('file.txt');
echo $content;
// 提取单个文件
$zip->extractTo('/tmp/extracted', ['file.txt', 'config.json']);
// 提取所有文件
$zip->extractTo('/tmp/extracted_all');
// 检查文件是否存在
echo "file.txt 存在: " . ($zip->locateName('file.txt') !== false ? 'yes' : 'no') . PHP_EOL;
$zip->close();修改 ZIP 文件
php
<?php
declare(strict_types=1);
$zip = new ZipArchive();
if ($zip->open('/tmp/archive.zip') !== true) {
throw new RuntimeException("无法打开 ZIP 文件");
}
// 删除文件
$zip->deleteName('old-file.txt');
$zip->deleteIndex(2);
// 重命名文件
$zip->renameName('file.txt', 'renamed.txt');
// 设置注释
$zip->setArchiveComment('这是一个归档文件');
// 设置文件注释
$zip->setCommentName('file.txt', '重要配置文件');
$zip->close();注意事项
- 使用
ZipArchive::CREATE | ZipArchive::OVERWRITE确保创建新文件 - 大文件添加时注意内存使用
- 提取时检查文件路径避免目录遍历攻击
下一节
继续学习:Zlib / Bzip2