有时候需要输出服务器上某个文件夹的全部文件,比如备份网站,用下面的php函数来实现。 函数库代码phpzip为:(请复制以下代码保存,以供调用) ? class phpzip{ private $strpath=../../@upload; private $datasec=array(); private $ctrl_dir=array(); pr
有时候需要输出服务器上某个文件夹的全部文件,比如备份网站,用下面的php函数来实现。
函数库代码phpzip为:(请复制以下代码保存,以供调用)
class phpzip{ private $strpath=../../@upload; private $datasec=array(); private $ctrl_dir=array(); private $eof_ctrl_dir=\x50\x4b\x05\x06\x00\x00\x00\x00; private $old_offset=0; //压缩后下载 function download($curdir,$zipfilename,$out){ $zipfilename=strtolower($zipfilename); $curdir=str_ireplace(basename($curdir),,$curdir); chdir($curdir.$this->strpath); header('content-encoding: none'); header('content-type: application/zip'); header('content-disposition: attachment ; filename='.str_replace(.zip,,basename($zipfilename)).'.zip'); header('pragma: no-cache'); header('expires: 0'); print($out); } //压缩后保存在服务器,默认在/@upload下 function savefile($curdir,$zipfilename,$out){ $curdir=str_ireplace(basename($curdir),,$curdir); chdir($curdir.$this->strpath); $fp=fopen($zipfilename,wb); fwrite($fp,$out,strlen($out)); fclose($fp); } //函数用途:压缩文件夹,递归逐层进行 //参数详解:$dir需要压缩的目录,$zipfilename压缩后的文件名及存放路径,$todo处理方式1提供下载2保存文件在服务器 function zipdir($dir,$zipfilename,$todo){ if(!@function_exists('gzcompress')){return 0;} @set_time_limit(0); $this->openfile($dir,$zipfilename); $out=$this -> filezip(); switch ($todo){ case 1: $this -> download(__file__,$zipfilename,$out); break; case 2: $this -> savefile(__file__,$zipfilename,$out); break; } } //函数用途:压缩文件,可以是单个也可以是数组的多个 //参数详解:$file需要压缩的文件(可为数组),$zipfilename压缩后的文件名及存放路径,$todo处理方式1提供下载2保存文件在服务器 function zipfile($file,$zipfilename,$todo){ if(!@function_exists('gzcompress')){return 0;} if(is_array($file)){ foreach($file as $filename){ if(is_file($filename)){ $fd= fopen ($filename, rb); $content= @fread($fd, filesize ($filename)); fclose ($fd); $filename= basename($filename); $this -> addfile($content, $filename); } } }else{ if(is_file($file)){ $fd= fopen ($file, rb); $content= @fread($fd, filesize($file)); fclose ($fd); $file= basename($file); $this -> addfile($content, $file); } } $out= $this -> filezip(); switch ($todo){ case 1: $this -> download(__file__,$zipfilename,$out); break; case 2: $this -> savefile(__file__,$zipfilename,$out); break; } } //递归取得下层文件夹下的文件 function openfile($path,$zipname){ $temp_path=$path; $temp_zip_path=$zipname; if($handle=@opendir($path)){ while(false !== ($file=readdir($handle))){ if($file !='.' and $file !='..'){ if(ereg('\.' ,$file.@basename())){ $fd=fopen($path.'/'.$file,r); $filevalue=@fread($fd,1024000); fclose ($fd); $this -> addfile($filevalue,$path.'/'.$file); }else{ $this ->openfile($path.'/'.$file,$zipname.'/'.$file); } } } $zipname=$temp_zip_path; $path=$temp_path; closedir($handle); } } function addfile($data,$name,$time=0){ $name=str_replace('\\','/',$name); $name=str_replace('./','',str_replace('../','',$name)); $dtime=dechex($this->unix2dostime($time)); $hexdtime='\x'.$dtime[6].$dtime[7].'\x'.$dtime[4].$dtime[5].'\x'.$dtime[2].$dtime[3].'\x'.$dtime[0].$dtime[1]; eval('$hexdtime='.$hexdtime.';'); $fr=\x50\x4b\x03\x04; $fr.=\x14\x00; $fr.=\x00\x00; $fr.=\x08\x00; $fr.=$hexdtime; $unc_len=strlen($data); $crc=crc32($data); $zdata=gzcompress($data); $c_len=strlen($zdata); $zdata=substr(substr($zdata,0,strlen($zdata) - 4),2); $fr.=pack('v',$crc); $fr.=pack('v',$c_len); $fr.=pack('v',$unc_len); $fr.=pack('v',strlen($name)); $fr.=pack('v',0); $fr.=$name; $fr.=$zdata; $fr.=pack('v',$crc); $fr.=pack('v',$c_len); $fr.=pack('v',$unc_len); $this -> datasec[]=$fr; $new_offset=strlen(implode('',$this->datasec)); $cdrec=\x50\x4b\x01\x02; $cdrec.=\x00\x00; $cdrec.=\x14\x00; $cdrec.=\x00\x00; $cdrec.=\x08\x00; $cdrec.=$hexdtime; $cdrec.=pack('v',$crc); $cdrec.=pack('v',$c_len); $cdrec.=pack('v',$unc_len); $cdrec.=pack('v',strlen($name) ); $cdrec.=pack('v',0 ); $cdrec.=pack('v',0 ); $cdrec.=pack('v',0 ); $cdrec.=pack('v',0 ); $cdrec.=pack('v',32 ); $cdrec.=pack('v',$this -> old_offset ); $this -> old_offset=$new_offset; $cdrec.=$name; $this -> ctrl_dir[]=$cdrec; } function filezip(){ $data=implode('',$this -> datasec); $ctrldir=implode('',$this -> ctrl_dir); return $data.$ctrldir.$this -> eof_ctrl_dir . pack('v',sizeof($this -> ctrl_dir)) . pack('v',sizeof($this -> ctrl_dir)) . pack('v',strlen($ctrldir)) . pack('v',strlen($data)).\x00\x00; } function unix2dostime($unixtime=0){ $timearray=($unixtime== 0) ? getdate() : getdate($unixtime); if($timearray['year'] > 1); } /* 解压缩部分 用途:解压缩文件 参数:$zn需要解压缩的zip文件及路径,$to解压缩的目的地 */ function unzip_file($zn, $to, $index = array(-1)){ $ok = 0; $zip = @fopen($zn, 'rb'); if(!$zip){return(-1);} $cdir = $this -> readcentraldir($zip, $zn); $pos_entry = $cdir['offset']; if(!is_array($index)){ $index = array($index); } for($i = 0; $index[$i];$i++){ if(intval($index[$i])!= $index[$i] || $index[$i] > $cdir['entries']){return(-1);} } for($i=0;$i readcentralfileheaders($zip); $header['index'] = $i; $pos_entry = ftell($zip); @rewind($zip); fseek($zip, $header['offset']); if(in_array(-1, $index) || in_array($i, $index)){$stat[$header['filename']] = $this -> extractfile($header, $to, $zip);} } fclose($zip); return $stat; } //取得压缩包内的文件信息 function get_list($zip_name){ $zip = @fopen($zip_name, 'rb'); if(!$zip){return(0);} $centd = $this -> readcentraldir($zip, $zip_name); @rewind($zip); @fseek($zip, $centd['offset']); for($i=0;$i readcentralfileheaders($zip); $header['index'] = $i; $info['filename'] = $header['filename']; $info['stored_filename'] = $header['stored_filename']; $info['size'] = $header['size']; $info['compressed_size'] = $header['compressed_size']; $info['crc'] = strtoupper(dechex($header['crc'])); $info['mtime'] = $header['mtime']; $info['comment'] = $header['comment']; $info['folder'] = ($header['external'] == 0x41ff0010 || $header['external'] == 16)?1:0; $info['index'] = $header['index']; $info['status'] = $header['status']; $ret[] = $info; unset($header); } return $ret; } function readfileheader($zip){ $binary_data = fread($zip, 30); $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/vcrc/vcompressed_size/vsize/vfilename_len/vextra_len', $binary_data); $header['filename'] = fread($zip, $data['filename_len']); if($data['extra_len'] != 0){$header['extra'] = fread($zip, $data['extra_len']);}else{$header['extra'] = '';} $header['compression'] = $data['compression']; $header['size'] = $data['size']; $header['compressed_size'] = $data['compressed_size']; $header['crc'] = $data['crc']; $header['flag'] = $data['flag']; $header['mdate'] = $data['mdate']; $header['mtime'] = $data['mtime']; if($header['mdate'] && $header['mtime']){ $hour = ($header['mtime']&0xf800) >> 11; $minute = ($header['mtime']&0x07e0) >> 5; $seconde = ($header['mtime']&0x001f) * 2; $year = (($header['mdate']&0xfe00) >> 9) + 1980; $month = ($header['mdate']&0x01e0) >> 5; $day = $header['mdate']&0x001f; $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); }else{ $header['mtime'] = time(); } $header['stored_filename'] = $header['filename']; $header['status'] = ok; return $header; } function readcentralfileheaders($zip){ $binary_data = fread($zip, 46); $header = unpack('vchkid/vid/vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/vcrc/vcompressed_size/vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/vexternal/voffset', $binary_data); if($header['filename_len'] != 0) $header['filename'] = fread($zip, $header['filename_len']); else $header['filename'] = ''; if($header['extra_len'] != 0) $header['extra'] = fread($zip, $header['extra_len']); else $header['extra'] = ''; if($header['comment_len'] != 0) $header['comment'] = fread($zip, $header['comment_len']); else $header['comment'] = ''; if($header['mdate'] && $header['mtime']){ $hour = ($header['mtime'] &0xf800) >> 11; $minute = ($header['mtime'] &0x07e0) >> 5; $seconde = ($header['mtime'] &0x001f) * 2; $year = (($header['mdate'] &0xfe00) >> 9) + 1980; $month = ($header['mdate'] &0x01e0) >> 5; $day = $header['mdate'] &0x001f; $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year); }else{ $header['mtime'] = time(); } $header['stored_filename'] = $header['filename']; $header['status'] = 'ok'; if(substr($header['filename'], -1) == '/') $header['external'] = 0x41ff0010; return $header; } function readcentraldir($zip, $zip_name){ $size = filesize($zip_name); if($size readfileheader($zip); if(substr($to, -1) != /) $to .= /; if(!@is_dir($to)) @mkdir($to, 0777); $pth = explode(/, dirname($header['filename'])); for($i = 0;isset($pth[$i]);$i++){ if(!$pth[$i]) continue; $pthss .= $pth[$i] . /; if(!is_dir($to . $pthss)) @mkdir($to . $pthss, 0777); } if(!($header['external'] == 0x41ff0010) && !($header['external'] == 16)){ if($header['compression'] == 0){ $fp = @fopen($to . $header['filename'], 'wb'); if(!$fp) return(-1); $size = $header['compressed_size']; while($size != 0){ $read_size = ($size
使用方法:
函数:文件压缩
压缩参数:需要压缩的文件或文件夹(文件可为数组),压缩后的zip文件名及存放路径,压缩类型1:文件夹2:文件,后续操作1:压缩后下载;2:存放在服务器上(默认为/@upload下)
压缩文件夹示例:tozip(./,../.date(d-h-i-s)..zip,1,2);
压缩文件示例:
$aaa=array(../1.txt,../2.txt);
tozip($aaa,../2.zip,2);
用法举例:
比如有这样一段文件结构:
home
--upload
----1.jpg
----2.jpg
----3.jpg
--web
----html
------inc
--------zip.php(这是上面的代码库)
------download.php
使用download.php中的代码,实现upload文件夹打包并自动下载:
zipdir($path,$zipfile,$todo); break; case 2: $zip->zipfile($path,$zipfile,$todo); break; } if($todo==1){ die(); }else{ return true; } } tozip(././upload, ../../upload.zip,1,1) ?>
原文地址:php打包下载整个文件夹或多文件, 感谢原作者分享。