因为自己需要PHP来压缩和解压文件,就上网查了一下发现没有合适的,我就自己研究了一下PHP手册中的ZipArchive类,在这里记录一下学到的东西。
PHP手册:http://php.net/manual/zh/class.ziparchive.php
1.ZipArchive类
首先来看看ZipArchive类的使用方法,这里我翻译了一下PHP手册中的函数说明:
函数 | 功能 |
---|---|
open | 打开一个zip文件 |
close | 关闭zip文件(文件是打开的或新建的) |
addEmptyDir | 添加一个新的目录 |
addFile | 添加一个文件 |
addFromString | 使用文件内容添加文件 |
addGlob | 使用glob模式添加文件 |
addPattern | 使用PCRE模式添加文件 |
deleteIndex | 使用索引删除一个文件或目录 |
deleteName | 使用名称删除一个文件或目录 |
extractTo | 解压Zip文件 |
getArchiveComment | 返回Zip文件的说明 |
getCommentIndex | 使用索引返回一个文件或目录的说明 |
getCommentName | 使用名称返回一个文件或目录的说明 |
getExternalAttributesIndex | 使用索引检索一个文件或目录的外部属性 |
getExternalAttributesName | 使用名称检索一个文件或目录的外部属性 |
getFromIndex | 使用索引返回文件的内容 |
getFromName | 使用文件名称返回文件的内容 |
getNameIndex | 使用索引返回一个文件或目录的名称 |
getStatusString | 返回错误状态消息 |
getStream | 得到一个文件处理程序中的文件或目录名称(只读)。 |
locateName | 返回文件或目录的索引 |
renameIndex | 通过索引重命名一个文件或目录 |
renameName | 通过文件名重命名一个文件或目录 |
setArchiveComment | 设置ZIP归档的说明 |
setCommentIndex | 通过索引设置一个文件或目录的说明 |
setCommentName | 通过文件名设置一个文件或目录的说明 |
setCompressionIndex | 通过索引设置一个文件或目录的压缩方法 |
setCompressionName | 通过文件名设置一个文件或目录的压缩方法 |
setEncryptionIndex | 通过索引设置一个文件或目录的加密方法 |
setEncryptionName | 通过文件名设置一个文件或目录的加密方法 |
setExternalAttributesIndex | 通过索引设置一个条目的外部属性 |
setExternalAttributesName | 通过文件名设置一个条目的外部属性 |
setPassword | 为ZIP文件设置密码 |
statIndex | 通过索引得到一个文件或目录的详细信息 |
statName | 通过文件名得到一个文件或目录的详细信息 |
unchangeAll | 撤销所有更改 |
unchangeArchive | 恢复所有更改 |
unchangeIndex | 通过索引恢复一个文件或目录的所有更改 |
unchangeName | 通过文件名恢复一个文件或目录的所有更改 |
还有 ZipArchive类的公有属性:
属性 | 说明 |
---|---|
status | ZipArchive 的状态 |
statusSys | ZipArchive 的系统状态 |
numFiles | 压缩包里的文件数 |
filename | 在文件系统里的文件名 |
comment | 压缩包的说明 |
看到有这么多函数是不是有些眼花?别怕,实现我们功能所使用的函数并不多。
2.使用ZipArchive压缩文件
压缩文件的步骤:
1. new
一个ZipArchive
类,并且新建一个ZIP文件
2. 向ZIP文件中添加文件或目录
3. 关闭ZIP文件
第一步,新建ZIP文件:
这步很简单:
$zipArc = new ZipArchive();
$zipArc->open('file.zip', ZipArchive::CREATE);
第二步,向ZIP文件中添加文件或目录:
从上面的函数列表中有几个函数可以添加文件或目录:
函数 | 功能 |
---|---|
addEmptyDir | 添加一个新的目录 |
addFile | 添加一个文件 |
addFromString | 使用文件内容添加文件 |
addGlob | 使用glob模式从一个目录添加文件 |
addPattern | 使用PCRE模式从一个目录添加文件 |
向ZIP文件添加一个空目录:
$zipArc->addEmptyDir ('newdir', ZipArchive::CREATE);
向ZIP文件添加一个文件:
$zipArc->addFile ('file1.txt');
使用文件内容向ZIP文件添加一个文件(意思就是把一段字符串保存到一个文件,并且把这个文件添加到ZIP文件中):
$zipArc->addFromString ('output.txt', 'hello world!');
上面的函数都只能添加一个文件或者目录,如果想批量添加内容怎么办呢?别急,addGlob()
和addPattern()
提供了我们需要的功能:
addGlobal()函数
bool ZipArchive::addGlob ( string $pattern [, int $flags = 0 [, array $options = array() ]] )
它使用glob模式向ZIP文件中添加文件,什么是glob模式呢?不懂请戳这里, 其实就是与linux命令中文件匹配一样的语法。
$zipArc->addGlob('class/*.php', 0, array('add_path' => 'phpclass/', 'remove_path' => 'class'))
这段代码把class
目录中后缀为'.php'
的文件添加到了ZIP文件中phpclass
目录中。
addPattern()函数
bool ZipArchive::addPattern ( string $pattern [, string $path = "." [, array $options = array() ]] )
它使用PCRE模式向ZIP文件中添加文件,什么是PCRE模式呢?不懂请戳这里, 其实就是pcre正则表达式。
$zipArc->addPattern('/\.(?:php)$/', 'class', array('add_path' => 'phpclass/', 'remove_path' => 'class'))
这段代码功能也是把class
目录中后缀为'.php'
的文件添加到了ZIP文件中phpclass
目录中。
有了这些,我们就可以写一个文件压缩函数了:
/**
* 使用ZIP压缩文件或目录
* @param [string] $toName 压缩后的文件名
* @param [string] $fromName 被压缩的文件或目录名
* @return [bool] 成功返回TRUE, 失败返回FALSE
*/
function zip($fromName, $toName)
{
if(!file_exists($fromName)){
return FALSE;
}
$zipArc = new ZipArchive();
if(!$zipArc->open($toName, ZipArchive::CREATE)){
return FALSE;
}
$res = is_dir($fromName) ? $zipArc->addGlob("{$fromName}/*") : $zipArc->addFile($fromName);
if(!$res){
$zipArc->close();
return FALSE;
}
return $zipArc->close();
}
测试代码:
if(zip('class', 'class.zip')){
echo "success";
}
else{
echo "failed";
}
这段代码就可以吧class
目录压缩到class.zip
文件了,是不是很好用呢,大家可以复制这个函数直接使用。
3.使用ZipArchive压缩文件
压缩文件的步骤:
1. 新建ZipArchive类,并且打开一个ZIP文件
2. 解压ZIP文件中的文件
3. 关闭ZIP文件
解压文件就简单多了:
$zipArc = new ZipArchive();
$zipArc->open('file.zip');
$zipArc->extractTo('dir');
上面的代码将会吧file.zip
文件解压到dir
目录下(不存在会自动创建)。
我这里也封装成函数给大家使用:
/**
* 解压一个ZIP文件
* @param [string] $toName 解压到哪个目录下
* @param [string] $fromName 被解压的文件名
* @return [bool] 成功返回TRUE, 失败返回FALSE
*/
function unzip($fromName, $toName)
{
echo filesize($fromName);
if(!file_exists($fromName)){
return FALSE;
}
$zipArc = new ZipArchive();
if(!$zipArc->open($fromName)){
return FALSE;
}
if(!$zipArc->extractTo($toName)){
$zipArc->close();
return FALSE;
}
return $zipArc->close();
}
测试代码:
if(unzip('class.zip', 'dir')){
echo "success";
}
else{
echo "failed";
}
上面的代码将会吧class.zip
文件解压到dir
目录下(不存在会自动创建)。