/* * 压缩文件 * */ function zip($files){ $zipName = 'download.zip'; $zip = new \ZipArchive;//使用本类,linux需开启zlib,windows需取消php_zip.dll前的注释 /* * 经过ZipArchive的对象处理zip文件 * $zip->open这个方法若是对zip文件对象操做成功,$zip->open这个方法会返回TRUE * $zip->open这个方法第一个参数表示处理的zip文件名。 * 这里重点说下第二个参数,它表示处理模式 * ZipArchive::OVERWRITE 老是以一个新的压缩包开始,此模式下若是已经存在则会被覆盖。 * ZIPARCHIVE::CREATE 若是不存在则建立一个zip压缩包,若存在系统就会往原来的zip文件里添加内容。 * * 这里不得不说一个大坑。 * 个人应用场景是须要每次都是建立一个新的压缩包,若是以前存在,则直接覆盖,不要追加 * so,根据官方文档和参考其余代码,$zip->open的第二个参数我应该用 ZipArchive::OVERWRITE * 问题来了,当这个压缩包不存在的时候,会报错:ZipArchive::addFile(): Invalid or uninitialized Zip object * 也就是说,经过个人测试发现,ZipArchive::OVERWRITE 不会新建,只有当前存在这个压缩包的时候,它才有效 * 因此个人解决方案是 $zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE) * * 以上总结基于我当前的运行环境来讲 * */ if ($zip->open($zipName, \ZIPARCHIVE::OVERWRITE | \ZIPARCHIVE::CREATE)!==TRUE) { exit('没法打开文件,或者文件建立失败'); } foreach($files as $val){ //$attachfile = $attachmentDir . $val['filepath']; //获取原始文件路径 if(file_exists($val)){ //addFile函数首个参数若是带有路径,则压缩的文件里包含的是带有路径的文件压缩 //若不但愿带有路径,则须要该函数的第二个参数 $zip->addFile($val, basename($val));//第二个参数是放在压缩包中的文件名称,若是文件可能会有重复,就须要注意一下 } } $zip->close();//关闭 if(!file_exists($zipName)){ exit("没法找到文件"); //即便建立,仍有可能失败 } return '打包成功'; } /* * 获取文件的路径及名称 * */ function traverse($path) { global $filePath;//获得外部定义的数组 $current_dir = opendir($path); //opendir()返回一个目录句柄,失败返回false while (($file = readdir($current_dir)) !== false) { //readdir()返回打开目录句柄中的一个条目 $sub_dir = $path . DIRECTORY_SEPARATOR . $file; //构建子目录路径 if ($file == '.' || $file == '..') { continue; } else if (is_dir($sub_dir)) { //若是是目录,进行递归 traverse($sub_dir); //嵌套遍历子文件夹 } else { //若是是文件,直接输出路径和文件名 $filePath[$path . '/' . $file] = $path . '/' . $file;//把文件路径赋值给数组 } } return $filePath; }