赞
踩
php ZipArchive可以说是php自带的一个函数了,他可对对文件进行压缩与解压缩处理,但是使用此类之前我们必须在php.ini中把extension=php_zip.dll前面的分号有没有去掉,然后再重启Apache这样才能使用这个类库。
ziparchive 可选参数,更多的使用例子,参考PHP - Manual: ZipArchive - 互联网笔记
添加一个新的文件目录
- <?php
- $zip = new ZipArchive;
- if ($zip->open('test.zip') === TRUE) {
- if($zip->addEmptyDir('newDirectory')) {
- echo 'Created a new root directory';
- } else {
- echo 'Could not create the directory';
- }
- $zip->close();
- } else {
- echo 'failed';
- }
- ?>
将文件添加到指定zip压缩包中。
添加的文件同时将内容添加进去
关闭ziparchive
将压缩包解压
打开一个zip压缩包
返回压缩时的状态内容,包括错误信息,压缩信息等等
删除压缩包中的某一个文件,如:deleteIndex(0)删除第一个文件
删除压缩包中的某一个文件名称,同时也将文件删除。
- <?php
- $zip = new ZipArchive;
- $res = $zip->open('test.zip', ZipArchive::CREATE);
- if ($res === TRUE) {
- $zip->addFromString('test.txt', 'file content goes here');
- $zip->addFile('data.txt', 'entryname.txt');
- $zip->close();
- echo 'ok';
- } else {
- echo 'failed';
- }
- ?>
- <?php
- $name = tempnam(sys_get_temp_dir(), "FOO");
- $zip = new ZipArchive;
- $res = $zip->open($name, ZipArchive::OVERWRITE); /* truncate as empty file is not valid */
- if ($res === TRUE) {
- $zip->addFile('data.txt', 'entryname.txt');
- $zip->close();
- echo 'ok';
- } else {
- echo 'failed';
- }
- ?>
注意,解压的文件夹中不要有中文!会引起乱码!
- $zip = new ZipArchive;//新建一个ZipArchive的对象
- /*
- 通过ZipArchive的对象处理zip文件
- $zip->open这个方法的参数表示处理的zip文件名。
- 如果对zip文件对象操作成功,$zip->open这个方法会返回TRUE
- */
-
- if ($zip->open('test.zip'))
- {
- $zip->extractTo('images');//假设解压缩到在当前路径下images文件夹的子文件夹php
- $zip->close();//关闭处理的zip文件
- }
- zip = new ZipArchive;
- $res = $zip->open('test.zip', ZipArchive::CREATE);
- if ($res) {
- $zip->addFromString('test.txt', 'file content goes here');
- $zip->close();
- echo 'ok';
- } else {
- echo 'failed';
- }
建议:$zip->open 使用try-catch去捕捉
- try {
- $zipResult = $zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
- //关闭处理的zip文件
- $zip->close();
- } catch (Exception $e) {
- exit( $e->getMessage());
- }
- function addFileToZip($path, $zip) {
-
- $handler = opendir($path); //打开当前文件夹由$path指定。
-
- /*
- 循环的读取文件夹下的所有文件和文件夹
- 其中$filename = readdir($handler)是每次循环的时候将读取的文件名赋值给$filename,
- 为了不陷于死循环,所以还要让$filename !== false。
- 一定要用!==,因为如果某个文件名如果叫'0',或者某些被系统认为是代表false,用!=就会停止循环
- */
-
- while (($filename = readdir($handler)) !== false) {
- //文件夹文件名字为'.'和‘..’,不要对他们进行操作
- if ($filename != "." && $filename != "..") {
- $filePath = "{$path}/{$filename}";
- // 如果读取的某个对象是文件夹,则递归
- if (is_dir($filePath)) {
- addFileToZip($filePath, $zip);
- } else {
- var_dump($filePath);
- // 将文件加入zip对象 传入第二个参数是避免出现目录层级的问题
- $zip->addFile($filePath, pathinfo($filePath, PATHINFO_BASENAME));
- }
- }
- }
- @closedir($path);
- }
- $STATICS_PATH = 'd:/xampp/htdocs/xin-card';
- $templatePath = '2023/03/0d9cf19188485dc70e21a1aae4ffad8d';
- // 要下载文件的最终目录
- $finalPath = "{$STATICS_PATH}/templates/{$templatePath}";
-
- if(!file_exists($finalPath)) {
- exit('路径不存在');
- }
-
- $zip = new ZipArchive();
- $zipName = time() . '.zip';
- // d:/xampp/htdocs/xin-card/zip/187823213.zip
- $zipPath = "{$STATICS_PATH}/zip/{$zipName}";
- try {
- $zipResult = $zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
- //调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
- addFileToZip($finalPath, $zip);
- //关闭处理的zip文件
- $zip->close();
- } catch (Exception $e) {
- exit( $e->getMessage());
- }
比如上面的addFileToZip方法,我一开始是这么写的:
- if (is_dir($filePath)) {
- addFileToZip($filePath, $zip);
- } else {
- $zip->addFile($filePath);
- }
这样写最终导致的后果就是生成的压缩文件,里面带有目录层级!
像这样:D:\xampp\htdocs\xin-card\statics\templates-packages\1679986315\D_\xampp\htdocs\xin-card\statics\templates-packages\2023\03\0d9cf19188485dc70e21a1aae4ffad8d
实际上只有最后的文件夹才是我想要的!
如果你使用php ZipArchive addFile 方法把多个文件压缩在1个目录时会产生一个问题,我们只想要在当前目录把所有文件放在一起,结果他安装每个文件的所在目录在当前目录创建一遍,解决方式如下:
- $allAttachment = [
- '1.png',
- '2.png',
- '3.png',
- '4.png',
- ];
-
- // 循环保存文件到Zip中
- foreach ($allAttachment as $attachmentItem) {
- $rootpath = 'd:/xampp/htdocs/xin-cards/';
- if ($attachmentItem) {
- $attachmentItem = "$rootpath/$attachmentItem";
- // 添加文件
- $zip->addFile($attachmentItem);
- // 对添加的文件重新命名,避免出现目录问题
- $zip->renameName($attachmentItem, basename($attachmentItem));
- }
- }
-
- // 关闭
- $zip->close();
- 如果不能解决您的问题,可以尝试如下方式
-
- // 添加文件
- $zip->addFile($attachmentItem, pathinfo($attachmentItem, PATHINFO_BASENAME));
以下是打包服务器上某个文件夹中所有文件,并下载的然后再删除压缩文件的全部代码:
- <?php
- $STATICS_PATH = PATH['statics'];
- $templatePath = '2023/03/0d9cf19188485dc70e21a1aae4ffad8d';
- $finalPath = "{$STATICS_PATH}/templates-packages/{$templatePath}";
- if(!file_exists($finalPath)) {
- exit('路径不存在');
- }
-
- function addFileToZip($path, $zip) {
-
- $handler = opendir($path); //打开当前文件夹由$path指定。
-
- /*
- 循环的读取文件夹下的所有文件和文件夹
- 其中$filename = readdir($handler)是每次循环的时候将读取的文件名赋值给$filename,
- 为了不陷于死循环,所以还要让$filename !== false。
- 一定要用!==,因为如果某个文件名如果叫'0',或者某些被系统认为是代表false,用!=就会停止循环
- */
-
- while (($filename = readdir($handler)) !== false) {
- //文件夹文件名字为'.'和‘..’,不要对他们进行操作
- if ($filename != "." && $filename != "..") {
- $filePath = "{$path}/{$filename}";
- // 如果读取的某个对象是文件夹,则递归
- if (is_dir($filePath)) {
- addFileToZip($filePath, $zip);
- } else {
- // 将文件加入zip对象 传入第二个参数是避免出现目录层级的问题
- $zip->addFile($filePath, pathinfo($filePath, PATHINFO_BASENAME));
- }
- }
- }
- @closedir($path);
- }
-
- $zip = new ZipArchive();
- $zipName = time() . '.zip';
- $zipPath = "{$STATICS_PATH}/templates-packages/{$zipName}";
- try {
- $zipResult = $zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE);
- //调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法
- addFileToZip($finalPath, $zip);
- //关闭处理的zip文件
- $zip->close();
-
- //下载文件
- $file = fopen($zipPath, "r");
- //返回的文件类型
- Header("Content-type: application/octet-stream");
- //按照字节大小返回
- Header("Accept-Ranges: bytes");
- //返回文件的大小
- Header("Accept-Length: " . filesize($zipPath));
- //这里设置客户端的弹出对话框显示的文件名
- Header("Content-Disposition: attachment; filename=" . $zipName);
- //一次性将数据传输给客户端
- //echo fread($file, filesize($filePath));
- //一次只传输1024个字节的数据给客户端
- //向客户端回送数据
- $buffer = 1024;//
- //判断文件是否读完
- while (!feof($file)) {
- //将文件读入内存
- $file_data = fread($file, $buffer);
- //每次向客户端回送1024个字节的数据
- echo $file_data;
-
- }
- //将生成的zip文件在服务器端删除,只需要客户端下载就行了
- @unlink($zipPath);
-
- } catch (Exception $e) {
- exit( $e->getMessage());
- }
解决phpZipArchive生成压缩文件带有目录层级的问题【阿里开发者社区】
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。