本文中使用的php版本:php7.4.27
单个文件的下载很容易实现,但是批量下载文件的话,虽然说比单文件下载要麻烦一些,但其实也还行。
批量下载文件的原理:将要批量下载的文件 打包压缩为zip文件,然后下载这一个压缩后的zip文件即可。使用php的内置类 ZipArchive() 可以让我们很容易实现文件的压缩和解压等。
注意点:配置php.ini,找到zip模块,并启用即可。咳咳~~ 虽然这个扩展一般都是默认启用的
创建一个新的zip文件
以下代码将创建一个新的zip文件(test_new.zip)并向其中添加一些文件。
$zip = new ZipArchive(); if($zip->open('test_new.zip', ZipArchive::CREATE) === true) { //将文件添加到zip文件 $zip->addFile('./test.html'); $zip->addFile('./composer.json'); //将random.txt文件添加到zip并将其重命名为newfile.txt //$zip->addFile('random.txt', 'newfile.txt'); //将有指定文本的new.txt文件添加到zip文件中(创建了一个new.txt文件添加到zip文件中,new.txt文件里面的内容就是: 哈哈qaq) //$zip->addFromString('new.txt', '哈哈qaq'); // 关闭zip文件 $zip->close(); } else { exit("zip文件创建失败"); }
open() 方法
open()方法的功能是打开一个 zip 文件,第一个参数是 文件名,第二个参数是 打开方式,打开方式可以接受一个预定义常量,下面是预定义常量的说明:
ZipArchive::OVERWRITE :总是以一个新的压缩包开始,此模式下如果之前已经存在相同的zip文件,则之前的zip文件会被覆盖。
ZipArchive::CREATE: 如果不存在 则创建一个zip压缩包。
ZipArchive::RDONLY: 只读模式打开压缩包。
ZipArchive::EXCL: 如果压缩包已经存在,则出错。
ZipArchive::CHECKCONS: 对压缩包执行额外的一致性检查,如果失败则显示错误。
我上面使用的是 ZipArchive::CREATE,也就是如果 zip 文件不存在就创建一个。
addFile() 方法
addFile 方法的功能是把文件添加到 zip 包中。第一个参数是要添加的文件名,第二个参数是添加到 zip 包中的名称。
//我要添加到 zip 包的文件是 log.txt 添加到 zip 包后在 zip 包中查看就是 log-backup.txt,相当于在添加的时候给文件改个名,成功会返回 true,否则返回 false 。 $zip->addFile('log.txt', 'log-backup.txt');
close() 方法
在操作完成后可以使用 close 关闭打开的 zip 包。
往zip文件中,添加多个文件
添加多个文件 除了多次调用addFile()方法外,也可以使用 addGlob() 方法来实现添加,addGlob() 方法 可以根据给定的过滤方式来获取目录下所有符合标准的文件。
下面创建一个 zip 包,然后把当前目录下所有 txt 结尾的文件都添加到 zip 包中:
$zip = new ZipArchive(); //创建ZipArchive类的对象 $zip->open('1.zip', ZipArchive::CREATE); //打开并创建一个1.zip文件 $zip->addGlob('*.txt'); //把当前目录下所有 .txt 结尾的文件都添加到 1.zip文件中 $zip->close(); //关闭打开的zip文件
如果我要添加当前目录下的所有文件 代码可以这样写:
$zip->addGlob('*');
注意点:addGlob() 方法 只能添加文件,即便用 * 也不会添加目录。
往zip文件中,添加目录
下面创建一个 zip 包,然后添加一个目录到 zip 包中:
$zip = new ZipArchive(); $zip->open('1.zip', ZipArchive::CREATE); $zip->addEmptyDir('temp'); $zip->close();
上面的 addEmptyDir() 方法只能添加目录,目录中的文件或目录是不会被添加到 zip 包中的,也就是说添加到 zip 包中的是空目录。因为 ZipArchive这个类中,没有可以自动递归添加目录下的文件或目录的方法,所以,如果要添加目录下的文件或目录就只能自己手动递归添加。
简单编写一个可以递归添加目录下的所有文件或目录的类:
class Zip { protected $zip = null; // ZipArchive 对象 protected $count = 0; // 记录文件数量 //添加单个文件或目录 public function add($fileName, $zipFileName = '') { if($zipFileName == '') { //如果zip文件名为空就使用传入的文件或目录名作为 zip 文件名 $zipFileName = $fileName . '.zip'; } $this->zip = new ZipArchive(); //创建ZipArchive类的对象 $this->zip->open($zipFileName, ZipArchive::CREATE); //打开一个zip文件 //判断传入的是否是一个目录 if(is_dir($fileName)) { $this->addDir($fileName); //调用添加目录方法 } else { //如果不是目录就直接添加文件 if($this->zip->addFile($fileName)) { $this->count ++; //成功添加后添加文件数量 +1 } } $this->zip->close(); //关闭打开的 zip 包 return $this->count; //返回已添加文件的数量 } //添加目录 public function addDir($dir) { $this->zip->addEmptyDir($dir); //添加目录 $fileList = glob($dir . '/*'); //获取路劲下的所有文件或目录 foreach($fileList as $file) { //是否是目录 if(is_dir($file)) { $this->addDir($file); //调用自身继续操作(这里就是递归点了) continue; //跳过本次循环 } //添加文件 if($this->zip->addFile($file, $file)) { $this->count ++; //成功添加后添加文件数量 +1 } } } }
上面封装的Zip类 可以调用 add() 方法来添加文件或目录,第一个参数 可以传入要添加的文件或目录,第二个参数是 zip包名称,如果传入的 zip 包不存在就会自动创建,如果省略第二个参数会使用文件名来作为 zip 包名。
下面调用一下上面封装的Zip 类:
$zip = new Zip(); $zip->add('src', 'src.zip'); // 调用 add 添加
使用上面的Zip类 无论传入的目录下 有多少文件或目录都能添加到zip文件里面去。
解压文件的相关方法及使用示例
下面把 src.zip 里的所有文件解压到 dir 目录:
$zip = new ZipArchive(); //创建ZipArchive类的对象 $zip->open('src.zip'); //打开 zip 包 $zip->extractTo('dir'); //把 zip 包内的所有文件解压到dir目录 $zip->close(); //关闭打开的 zip 包
解压文件使用的就是 extractTo() 方法,参数就是存放解压后的文件的目录,如果传入的目录不存在会自动创建。extractTo 成功返回 true ,失败返回 false 。
设置和获取注释
使用 WinRAR 等之类的压缩软件,可以查看一些网上下载的压缩包的时候 可以看到右侧有注释内容,PHP 内置的ZipArchive类,也能设置和查看注释内容。
下面给 src.zip 设置注释内容:
$zip = new ZipArchive(); $zip->open('src.zip'); $zip->setArchiveComment('这是一个 zip 压缩包'); //设置注释 $zip->close();
setArchiveComment()方法 可以给打开的压缩包设置注释内容,参数就是 注释内容,成功返回 true,失败返回 false 。
下面输出 src.zip 的注释内容:
$zip = new ZipArchive(); $zip->open('src.zip'); echo $zip->getArchiveComment(); //输出 注释内容 $zip->close();
查询相关方法及使用示例
count() 方法
count方法可以获取压缩包中的文件和目录数量,获取的是所有文件和目录的数量,包括深层级的目录和文件。
getNameIndex() 方法
getNameIndex 方法 可以根据传入的索引返回压缩包内文件的文件名,需要传入一个数字索引,返回对应文件的文件名。
下面循环输出 src.zip 里所有文件的文件名:
$zip = new ZipArchive(); $zip->open('src-all.zip'); for($i = 0; $i < $zip->count(); $i ++) { echo $zip->getNameIndex($i) . "/n"; //输出文件名 } $zip->close();
getFromIndex() 方法
getFromIndex 方法可以根据索引读取压缩包内的文件内容,第一个参数是文件索引,第二个参数是读取的字节数,0 为读取整个文件。
下面读取并输出 src.zip 中的第 2 个文件的内容,只读取 3 个字节:
$zip = new ZipArchive(); $zip->open('src.zip'); echo $zip->getFromIndex(2, 3); //读取并输出 $zip->close();
getFromName() 方法
getFromName 方法可以根据压缩包内的文件名读取压缩包内的文件内容,第一个参数是要读取的文件名,第二个参数是读取的字节数,0 为读取整个文件。getFromName 和上面的 getFromIndex 方法都是差不多的,只是 getFromName 方法传入的是文件名。
操作压缩包内的文件 的相关方法及使用示例
下面是一些操作压缩包内的文件的方法:
renameName() 方法
renameName 方法可以给压缩包内的文件重命名,第一个参数是要重命名的文件名,第二个参数是新文件名,成功返回 true ,失败返回 false 。
下面把 src.zip 里的 log.txt 重命名为 new-name.txt :
$zip = new ZipArchive(); $zip->open('src.zip'); $zip->renameName('log.txt', 'new-name.txt'); //重命名,将src.zip里的 log.txt 重命名为 new-name.txt : $zip->close();
renameIndex() 方法
renameIndex 方法和上面的 renameName 方法差不多,也是给压缩包里的文件重命名的,不过 renameIndex 的第一个参数是要重命名的文件索引,第二个参数是新文件名,成功返回 true ,失败返回 false
deleteName() 方法
deleteName 方法可以删除压缩包内的文件, 参数就是要删除的文件名,成功返回 true ,失败返回 false
下面删除 src.zip 中的 log.txt :
$zip = new ZipArchive(); $zip->open('src.zip'); $zip->deleteName('log.txt'); //删除src.zip压缩包里面的 log.txt文件 $zip->close();
deleteIndex() 方法
deleteIndex 方法和上面的 deleteName 差不多,也是删除压缩包里的文件,不过 deleteIndex 需要传入文件索引。
以上就是 PHP 操作 zip 压缩文件的常用的一些相关方法,更多方法可以查看 PHP 官网的 ZipArchive类 说明。
声明:禁止任何非法用途使用,凡因违规使用而引起的任何法律纠纷,本站概不负责。
精彩评论