# PHP ZIP压缩与解压:ZipArchive 类使用教程
在Web开发中,文件压缩和解压是常见的功能需求。PHP内置的ZipArchive类提供了完整的ZIP文件处理能力,无需依赖外部扩展。本文将详细介绍如何使用ZipArchive类进行文件压缩和解压操作。
## 一、ZipArchive类简介
ZipArchive是PHP内置的用于处理ZIP文件的类,自PHP 5.2.0起默认启用。它提供了以下主要功能:
- 创建新的ZIP压缩包
- 打开现有的ZIP文件
- 向ZIP中添加文件或目录
- 从ZIP中提取文件
- 删除ZIP中的文件
- 获取ZIP文件信息
## 二、基本使用方法
### 1. 创建ZipArchive实例
```php
$zip = new ZipArchive();
```
### 2. 打开或创建ZIP文件
```php
$filename = 'example.zip';
if ($zip->open($filename, ZipArchive::CREATE) === TRUE) {
// 操作ZIP文件
$zip->close(); // 操作完成后必须关闭
} else {
echo '无法打开或创建ZIP文件';
}
```
常用的打开模式:
- `ZipArchive::CREATE` - 如果不存在则创建
- `ZipArchive::OVERWRITE` - 总是新建(覆盖已存在的)
- `ZipArchive::EXCL` - 如果文件已存在则失败
- `ZipArchive::CHECKCONS` - 对ZIP进行额外的一致性检查
## 三、压缩文件操作
### 1. 添加单个文件到ZIP
```php
$zip->addFile('path/to/file.txt', 'newfilename.txt');
// 第二个参数可选,指定ZIP中的文件名
```
### 2. 添加目录到ZIP
```php
function addFolderToZip($folder, &$zip, $exclusiveLength) {
$handle = opendir($folder);
while (false !== $f = readdir($handle)) {
if ($f != '.' && $f != '..') {
$filePath = "$folder/$f";
// 删除前缀,保证相对路径
$localPath = substr($filePath, $exclusiveLength);
if (is_file($filePath)) {
$zip->addFile($filePath, $localPath);
} elseif (is_dir($filePath)) {
// 添加空目录
$zip->addEmptyDir($localPath);
addFolderToZip($filePath, $zip, $exclusiveLength);
}
}
}
closedir($handle);
}
// 使用示例
$folder = 'path/to/folder';
$zip->addEmptyDir('myfolder');
addFolderToZip($folder, $zip, strlen("$folder/"));
```
### 3. 从字符串添加文件
```php
$zip->addFromString('filefromstring.txt', '这是文件内容');
```
### 4. 设置压缩密码(PHP 7.2+)
```php
$zip->setPassword('secret');
// 添加的文件会被加密
$zip->addFile('file.txt');
```
## 四、解压文件操作
### 1. 解压全部文件
```php
$zip->open('example.zip');
$zip->extractTo('path/to/extract/');
$zip->close();
```
### 2. 解压指定文件
```php
$zip->open('example.zip');
$zip->extractTo('path/to/extract/', ['file1.txt', 'images/photo.jpg']);
$zip->close();
```
### 3. 解压加密ZIP(PHP 7.2+)
```php
$zip->open('encrypted.zip');
$zip->setPassword('secret');
$zip->extractTo('path/to/extract/');
$zip->close();
```
## 五、其他实用方法
### 1. 获取ZIP文件中的文件列表
```php
$zip->open('example.zip');
for ($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
echo "$filename\n";
}
$zip->close();
```
### 2. 获取文件信息
```php
$stat = $zip->statName('file.txt');
print_r($stat);
/*
Array
(
[name] => file.txt
[index] => 0
[crc] => 499465876
[size] => 1234
[mtime] => 1123164768
[comp_size] => 567
[comp_method] => 8
)
*/
```
### 3. 删除ZIP中的文件
```php
$zip->open('example.zip', ZipArchive::OVERWRITE);
$zip->deleteName('file.txt');
$zip->close();
```
### 4. 重命名ZIP中的文件
```php
$zip->open('example.zip');
$zip->renameName('oldname.txt', 'newname.txt');
$zip->close();
```
## 六、实战示例
### 1. 批量下载多个文件为ZIP
```php
// 创建ZIP
$zip = new ZipArchive();
$zipname = 'download_' . date('Ymd') . '.zip';
if ($zip->open($zipname, ZipArchive::CREATE) !== TRUE) {
exit("无法创建ZIP文件");
}
// 添加多个文件
$files = ['file1.pdf', 'file2.jpg', 'file3.docx'];
foreach ($files as $file) {
if (file_exists($file)) {
$zip->addFile($file);
}
}
$zip->close();
// 发送给浏览器下载
header('Content-Type: application/zip');
header('Content-Disposition: attachment; filename="' . $zipname . '"');
header('Content-Length: ' . filesize($zipname));
readfile($zipname);
// 删除临时文件
unlink($zipname);
```
### 2. 解压上传的ZIP文件
```php
if ($_FILES['zipfile']['error'] === UPLOAD_ERR_OK) {
$tmp_name = $_FILES['zipfile']['tmp_name'];
$zip = new ZipArchive();
if ($zip->open($tmp_name) === TRUE) {
$extractPath = 'uploads/' . uniqid();
mkdir($extractPath, 0777, true);
$zip->extractTo($extractPath);
$zip->close();
echo "文件解压成功到: $extractPath";
} else {
echo "无法打开ZIP文件";
}
} else {
echo "文件上传失败";
}
```
## 七、注意事项
1. **权限问题**:确保PHP有权限读写相关目录和文件
2. **内存限制**:处理大文件时可能需要调整PHP内存限制
3. **关闭ZIP文件**:操作完成后必须调用close()方法
4. **文件名编码**:中文文件名可能需要特殊处理编码问题
5. **安全考虑**:解压时要防范ZIP炸弹攻击
## 八、总结
PHP的ZipArchive类提供了完整的ZIP文件处理功能,通过简单的API即可实现文件的压缩和解压操作。无论是创建下载包、批量处理上传文件,还是进行文件备份,ZipArchive都能轻松胜任。
在实际开发中,可以结合业务需求封装更高级的工具类,使ZIP文件处理更加便捷高效。