ThinkPHP使用ZipArchive实现批量打包下载文件
上传的图片、Word、PDF较多时,批量打包下载方便快捷,下面我叫大家使用ZipArchive实现批量打包下载文件。
//下载 public function to_download() { $item = ["C:/Users/Administrator/Downloads/1.jpg","C:/Users/Administrator/Downloads/4.jpg"]; //批量下载 $zip = new \ZipArchive; //目錄 $path = "./temp/"; //压缩包的名称 $filename = 'temp.zip'; $zip_file = $path . $filename; //打开一个zip文件;\ZipArchive::OVERWRITE覆盖,\ZipArchive::CREATE創建 $zip->open($zip_file, \ZipArchive::OVERWRITE|\ZipArchive::CREATE); //创建临时目录(没有temp目录的需要先手动创建,或用mkdir创建) if (!is_dir($path)) { if ((mkdir($path, 0777, true)) === false) { return '临时目录创建失败!'; } } //把图片一张一张加进去压缩 foreach ($item as $key => $value) { //将文件添加到压缩包;第一個參數将文件写入zip,第二個參數是文件的重命名(同时防止多级目录出现) $zip->addFile($value,"$key.jpg"); } //关闭ziparchive $zip->close(); //可以直接重定向下载 // header('Location:'.$zip_file); //或者输出下载 header("Cache-Control: public"); header("Content-Description: File Transfer"); header('Content-disposition: attachment; filename='.basename($zip_file)); //获取文件名;basename:返回路径中的文件名部分, header("Content-Type: application/force-download");//强制下载 header("Content-Transfer-Encoding: binary");//二进制传输 header('Content-Length: '. filesize($zip_file)); //告诉浏览器,文件大小 readfile($zip_file); //下载后删除临时目录 if (is_dir($path)){//is_dir目录存在返回 TRUE $this->delDirAndFile($path); } }
下载后删除临时目录:
//删除目录 protected function delDirAndFile( $dirName ){ if($handle=opendir($dirName)){ while(false!==($item=readdir($handle))){ if($item!="."&&$item!=".."){ if(is_dir("$dirName/$item")){ $this->delDirAndFile("$dirName/$item"); }else{ unlink("$dirName/$item"); } } } closedir($handle); rmdir($dirName); } }
常遇到的问题:
1、创建临时文件失败
这是因为$zip->open,没有找到临时目录,我们需要先手动创建,或用mkdir创建:
//创建临时目录(没有temp目录的需要先手动创建,或用mkdir创建) if (!is_dir('./temp/')) { if ((mkdir($path, 0777, true)) === false) { return '临时目录创建失败!'; } }
2、ZipArchive::open()的错误使用
ZipArchive::open(),参数2是ZipArchive::CREATE,第一次会创建一个目录,但接着使用里面的压缩包每下载一次就叠加一次,所以这个适合第一次创建使用的;
ZipArchive::OVERWRITE的时候,当目标文件已经存在时,程序会生成一个新的同名文件覆盖原来的文件,但是,当这个文件不存在时,ZipArchive::open()将返回数字9,错误信息是“No such file.”。
如果想要实现文件存在时自动覆盖文件不存在时自动创建,那么应该同时使用ZipArchive::OVERWRITE和ZipArchive::CREATE。
$zip->open('wuxiancheng.cn.zip',ZipArchive::OVERWRITE|ZipArchive::CREATE);
3、ZipArchive压缩zip文件多级目录
$zip->addFile一般会出现多级目录,解决的方法就是添加文件后加个[路径]文件名 :
$zip->addFile ($dir.'test.zip','images1.jpg');//一级 /*压缩后的效果如 * test.zip * images1.zip */ $zip->addFile ($dir.'test.zip','images/images1.jpg');//二级 /*压缩后的效果如 * test.zip * imgages //目录 * images1.zip */
ZipArchive方法详细:https://nobige.cn/post/20180808-phpZipArchiveNdir/