• PHP打包下载整个文件夹或多文件



    有时候需要输出服务器上某个文件夹的全部文件,比如备份网站,用下面的PHP函数来实现。

    函数库代码PHPZip为:(请复制以下代码保存,以供调用)

    1. <?php
    2. Class PHPZip{
    3. Private $StrPath="../../@UpLoad";
    4. Private $datasec=array();
    5. Private $ctrl_dir=array();
    6. Private $eof_ctrl_dir="x50x4bx05x06x00x00x00x00";
    7. Private $old_offset=0;
    8. //压缩后下载
    9. Function DownLoad($curdir,$zipfilename,$out){
    10. $zipfilename=StrToLower($zipfilename);
    11. $curdir=Str_iReplace(basename($curdir),"",$curdir);
    12. chdir($curdir.$this->StrPath);
    13. header('Content-Encoding: none');
    14. header('Content-Type: application/zip');
    15. header('Content-Disposition: attachment ; filename='.Str_Replace(".zip","",basename($zipfilename)).'.zip');
    16. header('Pragma: no-cache');
    17. header('Expires: 0');
    18. print($out);
    19. }
    20. //压缩后保存在服务器,默认在/@Upload下
    21. Function SaveFile($curdir,$zipfilename,$out){
    22. $curdir=Str_iReplace(basename($curdir),"",$curdir);
    23. chdir($curdir.$this->StrPath);
    24. $fp=fopen($zipfilename,"wb");
    25. fwrite($fp,$out,strlen($out));
    26. fclose($fp);
    27. }
    28. //函数用途:压缩文件夹,递归逐层进行
    29. //参数详解:$dir需要压缩的目录,$zipfilename压缩后的文件名及存放路径,$Todo处理方式1提供下载2保存文件在服务器
    30. Function ZipDir($dir,$zipfilename,$Todo){
    31. IF(!@Function_exists('gzcompress')){Return 0;}
    32. @set_time_limit("0");
    33. $this->openFile($dir,$zipfilename);
    34. $out=$this -> filezip();
    35. Switch ($Todo){
    36. Case "1":
    37. $this -> DownLoad(__FILE__,$zipfilename,$out);
    38. Break;
    39. Case "2":
    40. $this -> SaveFile(__FILE__,$zipfilename,$out);
    41. Break;
    42. }
    43. }
    44. //函数用途:压缩文件,可以是单个也可以是数组的多个
    45. //参数详解:$file需要压缩的文件(可为数组),$zipfilename压缩后的文件名及存放路径,$Todo处理方式1提供下载2保存文件在服务器
    46. Function ZipFile($file,$zipfilename,$Todo){
    47. IF(!@Function_exists('gzcompress')){Return 0;}
    48. IF(is_array($file)){
    49. Foreach($file as $filename){
    50. IF(is_file($filename)){
    51. $fd= fopen ($filename, "rb");
    52. $content= @fread($fd, filesize ($filename));
    53. fclose ($fd);
    54. $filename= basename($filename);
    55. $this -> addFile($content, $filename);
    56. }
    57. }
    58. }Else{
    59. IF(is_file($file)){
    60. $fd= fopen ($file, "rb");
    61. $content= @fread($fd, filesize($file));
    62. fclose ($fd);
    63. $file= basename($file);
    64. $this -> addFile($content, $file);
    65. }
    66. }
    67. $out= $this -> filezip();
    68. Switch ($Todo){
    69. Case "1":
    70. $this -> DownLoad(__FILE__,$zipfilename,$out);
    71. Break;
    72. Case "2":
    73. $this -> SaveFile(__FILE__,$zipfilename,$out);
    74. Break;
    75. }
    76. }
    77. //递归取得下层文件夹下的文件
    78. Function openFile($path,$zipName){
    79. $temp_path=$path;
    80. $temp_zip_path=$zipName;
    81. IF($handle=@opendir($path)){
    82. While(false !== ($file=readdir($handle))){
    83. IF($file !='.' and $file !='..'){
    84. IF(ereg('.' ,$file.@basename())){
    85. $fd=fopen($path.'/'.$file,"r");
    86. $fileValue=@fread($fd,1024000);
    87. fclose ($fd);
    88. $this -> addFile($fileValue,$path.'/'.$file);
    89. }Else{
    90. $this ->openFile($path.'/'.$file,$zipName.'/'.$file);
    91. }
    92. }
    93. }
    94. $zipName=$temp_zip_path;
    95. $path=$temp_path;
    96. closedir($handle);
    97. }
    98. }
    99. Function addFile($data,$name,$time=0){
    100. $name=str_replace('\','/',$name);
    101. $name=str_replace('./','',str_replace('../','',$name));
    102. $dtime=dechex($this->unix2DosTime($time));
    103. $hexdtime='x'.$dtime[6].$dtime[7].'x'.$dtime[4].$dtime[5].'x'.$dtime[2].$dtime[3].'x'.$dtime[0].$dtime[1];
    104. Eval('$hexdtime="'.$hexdtime.'";');
    105. $fr="x50x4bx03x04";
    106. $fr.="x14x00";
    107. $fr.="x00x00";
    108. $fr.="x08x00";
    109. $fr.=$hexdtime;
    110. $unc_len=strlen($data);
    111. $crc=crc32($data);
    112. $zdata=gzcompress($data);
    113. $c_len=strlen($zdata);
    114. $zdata=substr(substr($zdata,0,strlen($zdata) - 4),2);
    115. $fr.=pack('V',$crc);
    116. $fr.=pack('V',$c_len);
    117. $fr.=pack('V',$unc_len);
    118. $fr.=pack('v',strlen($name));
    119. $fr.=pack('v',0);
    120. $fr.=$name;
    121. $fr.=$zdata;
    122. $fr.=pack('V',$crc);
    123. $fr.=pack('V',$c_len);
    124. $fr.=pack('V',$unc_len);
    125. $this -> datasec[]=$fr;
    126. $new_offset=strlen(implode('',$this->datasec));
    127. $cdrec="x50x4bx01x02";
    128. $cdrec.="x00x00";
    129. $cdrec.="x14x00";
    130. $cdrec.="x00x00";
    131. $cdrec.="x08x00";
    132. $cdrec.=$hexdtime;
    133. $cdrec.=pack('V',$crc);
    134. $cdrec.=pack('V',$c_len);
    135. $cdrec.=pack('V',$unc_len);
    136. $cdrec.=pack('v',strlen($name) );
    137. $cdrec.=pack('v',0 );
    138. $cdrec.=pack('v',0 );
    139. $cdrec.=pack('v',0 );
    140. $cdrec.=pack('v',0 );
    141. $cdrec.=pack('V',32 );
    142. $cdrec.=pack('V',$this -> old_offset );
    143. $this -> old_offset=$new_offset;
    144. $cdrec.=$name;
    145. $this -> ctrl_dir[]=$cdrec;
    146. }
    147. Function filezip(){
    148. $data=implode('',$this -> datasec);
    149. $ctrldir=implode('',$this -> ctrl_dir);
    150. Return
    151. $data.$ctrldir.$this -> eof_ctrl_dir .
    152. pack('v',sizeof($this -> ctrl_dir)) .
    153. pack('v',sizeof($this -> ctrl_dir)) .
    154. pack('V',strlen($ctrldir)) .
    155. pack('V',strlen($data))."x00x00";
    156. }
    157. Function unix2DosTime($unixtime=0){
    158. $timearray=($unixtime== 0) ? getdate() : getdate($unixtime);
    159. IF($timearray['year'] < 1980){
    160. $timearray['year']=1980;
    161. $timearray['mon']=1;
    162. $timearray['mday']=1;
    163. $timearray['hours']=0;
    164. $timearray['minutes']=0;
    165. $timearray['seconds']=0;
    166. }
    167. Return (($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
    168. }
    169. /*
    170. 解压缩部分
    171. 用途:解压缩文件
    172. 参数:$zn需要解压缩的zip文件及路径,$to解压缩的目的地
    173. */
    174. Function Unzip_File($zn, $to, $index = Array(-1)){
    175. $ok = 0;
    176. $zip = @fopen($zn, 'rb');
    177. IF(!$zip){Return(-1);}
    178. $cdir = $this -> ReadCentralDir($zip, $zn);
    179. $pos_entry = $cdir['offset'];
    180. IF(!is_array($index)){
    181. $index = array($index);
    182. }
    183. For($i = 0; $index[$i];$i++){
    184. IF(intval($index[$i])!= $index[$i] || $index[$i] > $cdir['entries']){Return(-1);}
    185. }
    186. For($i=0;$i<$cdir['entries'];$i++){
    187. @fseek($zip, $pos_entry);
    188. $header = $this -> ReadCentralFileHeaders($zip);
    189. $header['index'] = $i;
    190. $pos_entry = ftell($zip);
    191. @rewind($zip);
    192. fseek($zip, $header['offset']);
    193. IF(in_array("-1", $index) || in_array($i, $index)){$stat[$header['filename']] = $this -> ExtractFile($header, $to, $zip);}
    194. }
    195. fclose($zip);
    196. Return $stat;
    197. }
    198. //取得压缩包内的文件信息
    199. Function get_List($zip_name){
    200. $zip = @fopen($zip_name, 'rb');
    201. IF(!$zip){Return(0);}
    202. $centd = $this -> ReadCentralDir($zip, $zip_name);
    203. @rewind($zip);
    204. @fseek($zip, $centd['offset']);
    205. For($i=0;$i<$centd['entries'];$i++){
    206. $header = $this -> ReadCentralFileHeaders($zip);
    207. $header['index'] = $i;
    208. $info['filename'] = $header['filename'];
    209. $info['stored_filename'] = $header['stored_filename'];
    210. $info['size'] = $header['size'];
    211. $info['compressed_size'] = $header['compressed_size'];
    212. $info['crc'] = strtoupper(dechex($header['crc']));
    213. $info['mtime'] = $header['mtime'];
    214. $info['comment'] = $header['comment'];
    215. $info['folder'] = ($header['external'] == 0x41FF0010 || $header['external'] == 16)?1:0;
    216. $info['index'] = $header['index'];
    217. $info['status'] = $header['status'];
    218. $ret[] = $info;
    219. unset($header);
    220. }
    221. Return $ret;
    222. }
    223. Function ReadFileHeader($zip){
    224. $binary_data = fread($zip, 30);
    225. $data = unpack('vchk/vid/vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);
    226. $header['filename'] = fread($zip, $data['filename_len']);
    227. IF($data['extra_len'] != 0){$header['extra'] = fread($zip, $data['extra_len']);}Else{$header['extra'] = '';}
    228. $header['compression'] = $data['compression'];
    229. $header['size'] = $data['size'];
    230. $header['compressed_size'] = $data['compressed_size'];
    231. $header['crc'] = $data['crc'];
    232. $header['flag'] = $data['flag'];
    233. $header['mdate'] = $data['mdate'];
    234. $header['mtime'] = $data['mtime'];
    235. IF($header['mdate'] && $header['mtime']){
    236. $hour = ($header['mtime']&0xF800) >> 11;
    237. $minute = ($header['mtime']&0x07E0) >> 5;
    238. $seconde = ($header['mtime']&0x001F) * 2;
    239. $year = (($header['mdate']&0xFE00) >> 9) + 1980;
    240. $month = ($header['mdate']&0x01E0) >> 5;
    241. $day = $header['mdate']&0x001F;
    242. $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
    243. }Else{
    244. $header['mtime'] = time();
    245. }
    246. $header['stored_filename'] = $header['filename'];
    247. $header['status'] = "ok";
    248. Return $header;
    249. }
    250. Function ReadCentralFileHeaders($zip){
    251. $binary_data = fread($zip, 46);
    252. $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);
    253. IF($header['filename_len'] != 0)
    254. $header['filename'] = fread($zip, $header['filename_len']);
    255. Else $header['filename'] = '';
    256. IF($header['extra_len'] != 0)
    257. $header['extra'] = fread($zip, $header['extra_len']);
    258. Else $header['extra'] = '';
    259. IF($header['comment_len'] != 0)
    260. $header['comment'] = fread($zip, $header['comment_len']);
    261. Else $header['comment'] = '';
    262. IF($header['mdate'] && $header['mtime']){
    263. $hour = ($header['mtime'] &0xF800) >> 11;
    264. $minute = ($header['mtime'] &0x07E0) >> 5;
    265. $seconde = ($header['mtime'] &0x001F) * 2;
    266. $year = (($header['mdate'] &0xFE00) >> 9) + 1980;
    267. $month = ($header['mdate'] &0x01E0) >> 5;
    268. $day = $header['mdate'] &0x001F;
    269. $header['mtime'] = mktime($hour, $minute, $seconde, $month, $day, $year);
    270. }Else{
    271. $header['mtime'] = time();
    272. }
    273. $header['stored_filename'] = $header['filename'];
    274. $header['status'] = 'ok';
    275. IF(substr($header['filename'], -1) == '/')
    276. $header['external'] = 0x41FF0010;
    277. Return $header;
    278. }
    279. Function ReadCentralDir($zip, $zip_name){
    280. $size = filesize($zip_name);
    281. IF($size < 277){$maximum_size = $size;}Else{$maximum_size = 277;}
    282. @fseek($zip, $size - $maximum_size);
    283. $pos = ftell($zip);
    284. $bytes = 0x00000000;
    285. While($pos < $size){
    286. $byte = @fread($zip, 1);
    287. $bytes = ($bytes << 8) | Ord($byte);
    288. IF($bytes == 0x504b0506){
    289. $pos++;
    290. break;
    291. }
    292. $pos++;
    293. }
    294. $data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', fread($zip, 18));
    295. IF($data['comment_size'] != 0){$centd['comment'] = fread($zip, $data['comment_size']);}Else{$centd['comment'] = '';}
    296. $centd['entries'] = $data['entries'];
    297. $centd['disk_entries'] = $data['disk_entries'];
    298. $centd['offset'] = $data['offset'];
    299. $centd['disk_start'] = $data['disk_start'];
    300. $centd['size'] = $data['size'];
    301. $centd['disk'] = $data['disk'];
    302. Return $centd;
    303. }
    304. Function ExtractFile($header, $to, $zip){
    305. $header = $this -> readfileheader($zip);
    306. IF(substr($to, -1) != "/") $to .= "/";
    307. IF(!@is_dir($to)) @mkdir($to, 0777);
    308. $pth = explode("/", dirname($header['filename']));
    309. For($i = 0;isset($pth[$i]);$i++){
    310. IF(!$pth[$i]) continue;
    311. $pthss .= $pth[$i] . "/";
    312. IF(!is_dir($to . $pthss)) @mkdir($to . $pthss, 0777);
    313. }
    314. IF(!($header['external'] == 0x41FF0010) && !($header['external'] == 16)){
    315. IF($header['compression'] == 0){
    316. $fp = @fopen($to . $header['filename'], 'wb');
    317. IF(!$fp) Return(-1);
    318. $size = $header['compressed_size'];
    319. While($size != 0){
    320. $read_size = ($size < 2048 ? $size : 2048);
    321. $buffer = fread($zip, $read_size);
    322. $binary_data = pack('a' . $read_size, $buffer);
    323. @fwrite($fp, $binary_data, $read_size);
    324. $size -= $read_size;
    325. }
    326. fclose($fp);
    327. touch($to . $header['filename'], $header['mtime']);
    328. }Else{
    329. $fp = @fopen($to . $header['filename'] . '.gz', 'wb');
    330. IF(!$fp) Return(-1);
    331. $binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($header['compression']),
    332. Chr(0x00), time(), Chr(0x00), Chr(3));
    333. fwrite($fp, $binary_data, 10);
    334. $size = $header['compressed_size'];
    335. While($size != 0){
    336. $read_size = ($size < 1024 ? $size : 1024);
    337. $buffer = fread($zip, $read_size);
    338. $binary_data = pack('a' . $read_size, $buffer);
    339. @fwrite($fp, $binary_data, $read_size);
    340. $size -= $read_size;
    341. }
    342. $binary_data = pack('VV', $header['crc'], $header['size']);
    343. fwrite($fp, $binary_data, 8);
    344. fclose($fp);
    345. $gzp = @gzopen($to . $header['filename'] . '.gz', 'rb') or die("Cette archive est compress閑");
    346. IF(!$gzp) Return(-2);
    347. $fp = @fopen($to . $header['filename'], 'wb');
    348. IF(!$fp) Return(-1);
    349. $size = $header['size'];
    350. While($size != 0){
    351. $read_size = ($size < 2048 ? $size : 2048);
    352. $buffer = gzread($gzp, $read_size);
    353. $binary_data = pack('a' . $read_size, $buffer);
    354. @fwrite($fp, $binary_data, $read_size);
    355. $size -= $read_size;
    356. }
    357. fclose($fp);
    358. gzclose($gzp);
    359. touch($to . $header['filename'], $header['mtime']);
    360. @unlink($to . $header['filename'] . '.gz');
    361. }
    362. }
    363. Return true;
    364. }
    365. }
    366. ?>

    使用方法:

    函数:文件压缩
    压缩参数:需要压缩的文件或文件夹(文件可为数组),压缩后的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文件夹打包并自动下载:

    1. <?php
    2. Function Tozip($Path,$ZipFile,$Typ=1,$Todo=1){
    3. //IF(!is_writeable($Path)){Exit("文件夹不可写!");}
    4. $Path=Str_iReplace("\","/",($Path));
    5. IF(Is_Null($Path) Or Empty($Path) Or !IsSet($Path)){Return False;}
    6. IF(Is_Null($ZipFile) Or Empty($ZipFile) Or !IsSet($ZipFile)){Return False;}
    7. Include_once("inc/zip.php"); // 载入代码库,注意路径
    8. $zip = New PHPZip;
    9. IF(SubStr($Path,-1,1)=="/"){$Path=SubStr($Path,0,StrLen($Path)-1);}
    10. OB_end_clean();
    11. Switch ($Typ){
    12. Case "1":
    13. $zip->ZipDir($Path,$ZipFile,$Todo);
    14. Break;
    15. Case "2":
    16. $zip->ZipFile($Path,$ZipFile,$Todo);
    17. Break;
    18. }
    19. IF($Todo==1){
    20. Die();
    21. }Else{
    22. Return True;
    23. }
    24. }
    25. Tozip("././upload", "../../upload.zip",1,1)
    26. ?>

    //最然转载这个,但是个人认为这种相对路径,最好不要在上传下载的时候用,容易引发漏洞。能用绝对路径就用绝对路径...





  • 相关阅读:
    Bom入门
    Dom入门
    JavaScript对象
    Ultra-QuickSort——[归并排序、分治求逆序对]
    UVA 11212 Editing a Book [迭代加深搜索IDA*]
    Anagram——[枚举全排列]
    Black Box--[优先队列 、最大堆最小堆的应用]
    Argus--[优先队列]
    UVa1601
    UVa 10603 Fill [暴力枚举、路径搜索]
  • 原文地址:https://www.cnblogs.com/sunscheung/p/4839435.html
Copyright © 2020-2023  润新知