在用CI搭建的项目中,需要将文件压缩打包下载,但不管怎么配置服务器,都会报内存溢出错误,没办法,只能采用PHP自带的zip类,先将文件移至某个具体的路径,然后进行压缩,压缩完成之后,将移动文件删除,回调压缩包路径,因很多是个人扩展,关键的几句代码在方法内,使用过程中
遇到$zip->addFile($path . "/" . $filename);,这样会产生将目录压缩进去,查了下资料,这个方法后面还有个参数,带上之后,就只压缩当前的文件夹了:
$zip->addFile($path . "/" . $filename,$filename);
封装方法如下:
/** * @uses 压缩文件处理 * @author jhl */ public function handle_zip($download_id=""){ $download_id = intval($download_id); if(!$download_id){ echo 2;exit; } //通过审核才能下载 $download_info = $this->db->select("upload_file, download_count, integration, upload_user_id,zip_file_path")->where("download_id = {$download_id}","",false)->get($this->db->dbprefix("download"))->row_array(); if(empty($download_info)) { echo 3;exit; } $this->load->library("log_handle"); $upload_list = $this->db->select('upload_file')->where("download_id = {$download_id}", "", false)->get($this->db->dbprefix('download'))->row_array(); //检测压缩文件是否存在 $zip_file_path = $this->zip_file_path; $zip_file_name = $this->zip_file_name;//双MD5加密 //创建目录 create_path($zip_file_path,0777,true); //文件数组 $upload_list = $this->log_handle->trans_string_arr($upload_list['upload_file']); //复制文件,打包下载 foreach ($upload_list as $key=>$value){ $file_path = $_SERVER["DOCUMENT_ROOT"].$value; if(file_exists($file_path)){ $file_name = substr($value, strrpos($value,'/')+1); if(!file_exists($zip_file_path."/".$file_name)){ copy($file_path,$zip_file_path."/".$file_name); } }else{ unset($upload_list[$key]); } } if(empty($upload_list)){ echo 4;exit; } $zip = new ZipArchive(); if ($zip->open($zip_file_path."/".$zip_file_name, ZipArchive::OVERWRITE) === TRUE) {//这个配置绝对没有错 $this->addFileToZip($zip_file_path, $zip); //调用方法,对要打包的根目录进行操作,并将ZipArchive的对象传递给方法 $zip->close(); //关闭处理的zip文件 } //压缩完成,删除移动文件 $this->load->helper('directory'); $map = directory_map($zip_file_path."/"); foreach ($map as $keym=>$valuem){ if($valuem != $zip_file_name){ @unlink($zip_file_path."/".$valuem); } } $this->db->set('zip_file_path', $this->file_path.'/'.$this->zip_file_name)->where('download_id', $download_id)->update($this->db->dbprefix('download')); //若压缩成功,删除原先文件 @unlink($_SERVER["DOCUMENT_ROOT"].$download_info["zip_file_path"]); echo 1;exit; } public function addFileToZip($path, $zip) { $handler = opendir($path); //打开当前文件夹由$path指定。 while (($filename = readdir($handler)) !== false) { if ($filename != "." && $filename != "..") {//文件夹文件名字为'.'和‘..’,不要对他们进行操作 if (is_dir($path . "/" . $filename)) {// 如果读取的某个对象是文件夹,则递归 $this->addFileToZip($path . "/" . $filename, $zip); } else { //将文件加入zip对象 $zip->addFile($path . "/" . $filename,$filename); } } } @closedir($path); }