上次遇到一個需要打包下載批量圖片的問題,找了一下發現這個好方法,記錄一下。
首先新建一個zipfile打包類:
代碼如下復制代碼
<?php
classzipfile {
var$datasec=array();
var$ctrl_dir=array();
var$eof_ctrl_dir="\x50\x4b\x05\x06\x00\x00\x00\x00";
var$old_offset= 0;
functionunix2_dostime($unixtime= 0){
$timearray= ($unixtime== 0) ?getdate() :getdate($unixtime);
if($timearray['year'] < 1980){
$timearray['year'] = 1980;
$timearray['mon'] = 1;
$timearray['mday'] = 1;
$timearray['hours'] = 0;
$timearray['minutes'] = 0;
$timearray['seconds'] = 0;
}
return(($timearray['year'] - 1980) << 25) | ($timearray['mon'] << 21) | ($timearray['mday'] << 16) | ($timearray['hours'] << 11) | ($timearray['minutes'] << 5) | ($timearray['seconds'] >> 1);
}
functionadd_file($data,$name,$time= 0){
$name=str_replace('\\','/',$name);
$dtime=dechex($this->unix2_dostime($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);
$zdata=substr(substr($zdata, 0,strlen($zdata)- 4), 2);
$c_len=strlen($zdata);
$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;
$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 +=strlen($fr);
$cdrec.=$name;
$this->ctrl_dir[] =$cdrec;
}
functionadd_path($path,$l= 0){
$d= @opendir($path);
$l=$l> 0 ?$l:strlen($path) + 1;
while($v= @readdir($d)){
if($v=='.'||$v=='..'){
continue;
}
$v=$path.'/'.$v;
if(is_dir($v)){
$this->add_path($v,$l);
}else{
$this->add_file(file_get_contents($v),substr($v,$l));
}
}
}
functionfile(){
$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";
}
functionadd_files($files){
foreach($filesas$file){
if(is_file($file)){
$data= implode("", file($file));
$this->add_file($data,$file);
}
}
}
functionoutput($file){
$fp=fopen($file,"w");
fwrite($fp,$this->file ());
fclose($fp);
}
}
//下面是實例操作過程:
$dfile= tempnam('/tmp','tmp');//產生一個臨時文件,用於緩存下載文件
$zip=newzipfile();
//----------------------
$filename='image.zip'//下載的默認文件名
//以下是需要下載的圖片數組信息,將需要下載的圖片信息轉化為類似即可
$image=array(
array('image_src'=>'pic1.jpg','image_name'=>'圖片1.jpg'),
array('image_src'=>'pic2.jpg','image_name'=>'pic/圖片2.jpg'),
);
foreach($imageas$v){
$zip->add_file(file_get_contents($v['image_src']),$v['image_name']);
// 添加打包的圖片,第一個參數是圖片內容,第二個參數是壓縮包裡面的顯示的名稱, 可包含路徑
// 或是想打包整個目錄 用 $zip->add_path($image_path);
}
//----------------------
$zip->output($dfile);
// 下載文件
ob_clean();
header('Pragma: public');
header('Last-Modified:'.gmdate('D, d M Y H:i:s') .'GMT');
header('Cache-Control:no-store, no-cache, must-revalidate');
header('Cache-Control:pre-check=0, post-check=0, max-age=0');
header('Content-Transfer-Encoding:binary');
header('Content-Encoding:none');
header('Content-type:multipart/form-data');
header('Content-Disposition:attachment; filename="'.$filename.'"');//設置下載的默認文件名
header('Content-length:'.filesize($dfile));
$fp=fopen($dfile,'r');
while(connection_status() == 0 &&$buf= @fread($fp, 8192)){
echo$buf;
}
fclose($fp);
@unlink($dfile);
@flush();
@ob_flush();
exit();
?>