PHP ZIP压缩文件与解压文件案例

学什么PHPZIP压缩与解压

<?PHP
类PHPZip
{
    private $ ctrl_dir = array();
    private $ datasec = array();


    / ******************* *********
     *压缩部分
     ************************************************** ******** /
    // ------------------------------------------------ ------ //
    //#遍历指定文件夹
    //
    // $ archive = new PHPZip();
    // $ filelist = $ archive-> visitFile(文件夹路径);
    //打印“当前文件夹的文件:<p> \ r \ n”;
    // foreach($ filelist as $ file)
    // printf(“%s <br> \ r \ n”,$ file);
    // ------------------------------------------------ ------ //
    var $ fileList = array();
    公共职能visitFile($路径)
    {
        全局$ fileList;
        $ path = str_replace(“\\”,“/”,$ path);
        $ fdir = dir($ path);
    
        while(($ file = $ fdir-> read())!== false)
        {
            if($ file =='。'|| $ file =='..'){continue; }
    
            $ pathSub = preg_replace(“* / {2,} *”,“/”,$ path。“/”。$ file); //替换多个反斜杠
            $ fileList [] = is_dir($ pathSub)?$ pathSub。“/”:$ pathSub;
            if(is_dir($ pathSub)){$ this-> visitFile($ pathSub); }
        }
        $ fdir->接近();
        返回$ fileList;
    }
    
    
    私有函数unix2DosTime($ unixtime = 0)
    {
        $ timearray =($ unixtime == 0)?getdate():getdate($ unixtime);

        如果($ timearray ['year'] <1980)
        {
            $ timearray ['year'] = 1980;
            $ timearray ['mon'] = 1;
            $ timearray ['mday'] = 1;
            $ timearray ['hours'] = 0;
            $ timearray ['minutes'] = 0;
            $ timearray ['seconds'] = 0;
        }

        (($ timearray ['year']  -  1980)<< 25)
                | ($ timearray ['mon'] << 21)
                | ($ timearray ['mday'] << 16)
                | ($ timearray ['hours'] << 11)
                | ($ timearray ['minutes'] << 5)
                | ($ timearray ['seconds'] >> 1);
    }
    
    
    var $ old_offset = 0;
    私人函数addFile($ data,$ filename,$ time = 0)
    {
        $ filename = str_replace('\\','/',$ filename);

        $ 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($ filename));
        $ fr。= pack('v',0);
        $ fr。= $ filename;

        $ 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($ filename));
        $ 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。= $ filename;
        $ this-> ctrl_dir [] = $ cdrec;
    }
    
    
    var $ eof_ctrl_dir =“\ x50 \ x4b \ x05 \ x06 \ x00 \ x00 \ x00 \ x00”;
    私人功能文件()
    {
        $ data = implode('',$ this-> datasec);
        $ ctrldir = implode('',$ this-> ctrl_dir);

        返回$数据
               。$ ctrldir
               。$这个 - > 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”;
    }

    
    // ------------------------------------------------ ------ //
    //#压缩到服务器
    //
    // $ archive = new PHPZip();
    // $ archive-> Zip(“需压缩的文件所在目录”,“ZIP压缩文件名”); 
    // ------------------------------------------------ ------ //
    公共函数Zip($ dir,$ saveName)
    {
        如果(@!function_exists('gzcompress')){return; }

  // ob_end_clean();
        $ filelist = $ this-> visitFile($ dir);
        if(count($ filelist)== 0){return; }

        foreach($ filelist为$ file)
        {
            如果(!file_exists($ file)||!is_file($ file)){continue; }
            
            $ fd = fopen($ file,“rb”);
            $ content = @fread($ fd,filesize($ file));
            FCLOSE($ FD);

            // 1.删除$ dir的字符(./folder/file.txt删除./文件夹/)
            // 2.如果存在/就删除(/file.txt删除/)
            $ file = substr($ file,strlen($ dir));
            if(substr($ file,0,1)==“\\”|| substr($ file,0,1)==“/”){$ file = substr($ file,1); }
            
            $ this-> addFile($ content,$ file);
        }
        $ out = $ this-> file();

        $ fp = fopen($ saveName,“wb”);
        fwrite($ fp,$ out,strlen($ out));
        FCLOSE($ FP);
    }


    // ------------------------------------------------ ------ //
    //#压缩并直接下载
    //
    // $ archive = new PHPZip();
    // $ archive-> ZipAndDownload(“需压缩的文件所在目录”);
    // ------------------------------------------------ ------ //
    公共函数ZipAndDownload($ dir,$ saveName)
    {
        如果(@!function_exists('gzcompress')){return; }

        ob_end_clean();
        $ filelist = $ this-> visitFile($ dir);
        if(count($ filelist)== 0){return; }

        foreach($ filelist为$ file)
        {
            如果(!file_exists($ file)||!is_file($ file)){continue; }
            
            $ fd = fopen($ file,“rb”);
            $ content = @fread($ fd,filesize($ file));
            FCLOSE($ FD);

            // 1.删除$ dir的字符(./folder/file.txt删除./文件夹/)
            // 2.如果存在/就删除(/file.txt删除/)
            $ file = substr($ file,strlen($ dir));
            if(substr($ file,0,1)==“\\”|| substr($ file,0,1)==“/”){$ file = substr($ file,1); }
            
            $ this-> addFile($ content,$ file);
        }
        $ out = $ this-> file();

        @header('Content-Encoding:none');
        @header('Content-Type:application / zip');
        @header('Content-Disposition:attachment; filename ='。$ saveName。'。zip');
        @header('Pragma:no-cache');
        @header('Expires:0');
        打印($出);
    }
    
    
    / ******************* *********
     *解压部分
     ************************************************** ******** /
    // ------------------------------------------------ ------ //
    // ReadCentralDir($ zip,$ zipfile)
    // $ zip是经过@fopen($ zipfile,'rb')打开的
    // $ zipfile是zip文件的路径
    // ------------------------------------------------ ------ //
    私人函数ReadCentralDir($ zip,$ zipfile)
    {
        $ size = filesize($ zipfile);
        $ max_size =($ size <277)?$ size:277;
        
        @fseek($ zip,$ size  -  $ max_size);
        $ pos = ftell($ zip);
        $ bytes = 0x00000000;
        
        while($ pos <$ size)
        {
            $ byte = @fread($ zip,1);
            $ bytes =($ bytes << 8)| 奥德($字节);
            $ POS ++;
            if($ bytes == 0x504b0506){break; }
        }
        
        $ data = unpack('vdisk / vdisk_start / vdisk_entries / ventries / Vsize / Voffset / vcomment_size',fread($ zip,18));

        $ centd ['comment'] =($ data ['comment_size']!= 0)?fread($ zip,$ data ['comment_size']):''; //注释
        $ centd ['entries'] = $ data ['entries'];
        $ centd ['disk_entries'] = $ data ['disk_entries'];
        $ centd ['offset'] = $ data ['offset'];
        $ centd ['disk_start'] = $ data ['disk_start'];
        $ centd ['size'] = $ data ['size'];
        $ centd ['disk'] = $ data ['disk'];
        返回$ centd;
    }
    
    
    私人函数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);

        $ header ['filename'] =($ header ['filename_len']!= 0)?fread($ zip,$ header ['filename_len']):'';
        $ header ['extra'] =($ header ['extra_len']!= 0)?fread($ zip,$ header ['extra_len']):'';
        $ header ['comment'] =($ header ['comment_len']!= 0)?fread($ zip,$ header ['comment_len']):'';


        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; } //判断是否文件夹
        返回$ header;
    }


    私人函数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']);
        $ header ['extra'] =($ data ['extra_len']!= 0)?fread($ zip,$ data ['extra_len']):'';
        $ 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);
        }其他{
            $ header ['mtime'] = time();
        }

        $ header ['stored_filename'] = $ header ['filename'];
        $ header ['status'] =“ok”;
        返回$ header;
    }


    私人函数ExtractFile($ header,$ to,$ zip)
    {
        $ header = $ this-> readfileheader($ zip);
        
        if(substr($ to,-1)!=“/”){$ to。=“/”; }
        如果(!@ is_dir($ to)){@mkdir($ to,0777); }
        
        $ pth = explode(“/”,dirname($ header ['filename']));
        for($ i = 0; isset($ pth [$ i]); $ i ++){
            如果(!$ pth [$ i]){continue; }
            $ pthss。= $ pth [$ i]。“/”;
            if(!is_dir($ to。$ pthss)){@mkdir($ to。$ pthss,0777); }
        }
        
        if(!($ header ['external'] == 0x41FF0010)&&!($ header ['external'] == 16))
        {
            如果($ header ['compression'] == 0)
            {
                $ fp = @fopen($ to。$ header ['filename'],'wb');
                if(!$ fp){return(-1); }
                $ size = $ header ['compressed_size'];
                
                而($ size!= 0)
                {
                    $ read_size =($ size <2048?$ size:2048);
                    $ buffer = fread($ zip,$ read_size);
                    $ binary_data = pack('a'。$ read_size,$ buffer);
                    @fwrite($ fp,$ binary_data,$ read_size);
                    $ size  -  = $ read_size;
                }
                FCLOSE($ FP);
                touch($ to。$ header ['filename'],$ header ['mtime']);
            
            }其他{
                
                $ fp = @fopen($ to。$ header ['filename']。'。gz','wb');
                if(!$ fp){return(-1); }
                $ binary_data = pack('va1a1Va1a1',0x8b1f,Chr($ header ['compression']),Chr(0x00),time(),Chr(0x00),Chr(3));
                
                fwrite($ fp,$ binary_data,10);
                $ size = $ header ['compressed_size'];
                
                而($ size!= 0)
                {
                    $ read_size =($ size <1024?$ size:1024);
                    $ buffer = fread($ zip,$ read_size);
                    $ binary_data = pack('a'。$ read_size,$ buffer);
                    @fwrite($ fp,$ binary_data,$ read_size);
                    $ size  -  = $ read_size;
                }
                
                $ binary_data = pack('VV',$ header ['crc'],$ header ['size']);
                fwrite($ fp,$ binary_data,8);
                FCLOSE($ FP);
                
                $ gzp = @gzopen($ to。$ header ['filename']。'。gz','rb')或die(“Cette archive est compress!”);
                
                if(!$ gzp){return(-2); }
                $ fp = @fopen($ to。$ header ['filename'],'wb');
                if(!$ fp){return(-1); }
                $ size = $ header ['size'];
                
                而($ size!= 0)
                {
                    $ read_size =($ size <2048?$ size:2048);
                    $ buffer = gzread($ gzp,$ read_size);
                    $ binary_data = pack('a'。$ read_size,$ buffer);
                    @fwrite($ fp,$ binary_data,$ read_size);
                    $ size  -  = $ read_size;
                }
                FCLOSE($ FP); gzclose($滚子坪);
                
                touch($ to。$ header ['filename'],$ header ['mtime']);
                @unlink($到$头[ '文件名']。 'GZ。');
            }
        }
        返回true;
    }
    
    
    // ------------------------------------------------ ------ //
    //#解压文件
    //
    // $ archive = new PHPZip();
    // $ zipfile =“ZIP压缩文件名”;
    // $ savepath =“解压缩目录名”;
    // $ zipfile = $ unzipfile;
    // $ savepath = $ unziptarget;
    // $ array = $ archive-> GetZipInnerFilesInfo($ zipfile);
    // $ filecount = 0;
    // $ dircount = 0;
    // $ failfiles = array();
    // set_time_limit(0); //修改为不限制超时时间(默认为30秒)
    //
    // for($ i = 0; $ i <count($ array); $ i ++){
    // if($ array [$ i] [folder] == 0){
    // if($ archive-> unZip($ zipfile,$ savepath,$ i)> 0){
    // $ filecount ++;
    //} else {
    // $ failfiles [] = $ array [$ i] [filename];
    //}
    //} else {
    // $ dircount ++;
    //}
    //}
    // set_time_limit(30);
    // printf(“文件夹:%d&nbsp;&nbsp;&nbsp;&nbsp;解压文件:%d&nbsp;&nbsp;&nbsp;&nbsp;失败:%d <br> \ r \ n”,$ dircount,$ filecount,count( $ failfiles));
    // if(count($ failfiles)> 0){
    // foreach($ failfiles as $ file){
    // printf(“&middot;%s <br> \ r \ n”,$ file);
    //}
    //}
    // ------------------------------------------------ ------ //
    公共函数unZip($ zipfile,$ to,$ index = Array(-1))
    {
        $ ok = 0;
        $ zip = @fopen($ zipfile,'rb');
        如果(!$ zip){return(-1); }
        
        $ cdir = $ this-> ReadCentralDir($ zip,$ zipfile);
        $ 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'])
            {
                返回(-1);
            }
        }
        
        for($ i = 0; $ i <$ cdir ['entries']; $ i ++)
        {
            @fseek($ zip,$ pos_entry);
            $ header = $ this-> 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);
        返回$ stat;
    }
    
    
    
    
    
    / ******************* *********
     *其它部分
     ************************************************** ******** /
    // ------------------------------------------------ ------ //
    //#获取被压缩文件的信息
    //
    // $ archive = new PHPZip();
    // $ array = $ archive-> GetZipInnerFilesInfo(ZIP压缩文件名);
    // for($ i = 0; $ i <count($ array); $ i ++){
    // printf(“<b>&middot;%s </ b> <br> \ r \ n”,$ array [$ i] [filename]);
    // foreach($ array [$ i] as $ key => $ value)
    // printf(“%s =>%s <br> \ r \ n”,$ key,$ value);
    // print“\ r \ n <p> ------------------------------------ <p> \ r \ n \ r \ n“个;
    //}
    // ------------------------------------------------ ------ //
    公共函数GetZipInnerFilesInfo($ zipfile)
    {
        $ zip = @fopen($ zipfile,'rb');
        如果(!$ zip){return(0); }
        $ centd = $ this-> ReadCentralDir($ zip,$ zipfile);
        
        @rewind($ ZIP);
        @fseek($ zip,$ centd ['offset']);
        $ ret = array();

        for($ i = 0; $ i <$ centd ['entries']; $ i ++)
        {
            $ header = $ this-> ReadCentralFileHeaders($ zip);
            $ header ['index'] = $ i;
            $ info = array(
                'filename'=> $ header ['filename'],//文件名
                'stored_filename'=> $ header ['stored_filename'],//压缩后文件名
                'size'=> $ header ['size'],//大小
                'compressed_size'=> $ header ['compressed_size'],//压缩后大小
                'crc'=> strtoupper(dechex($ header ['crc'])),// CRC32
                'mtime'=> date(“Ymd H:i:s”,$ header ['mtime']),//文件修改时间
                'comment'=> $ header ['comment'],//注释
                'folder'=>($ header ['external'] == 0x41FF0010 || $ header ['external'] == 16)?1:0,//是否为文件夹
                'index'=> $ header ['index'],//文件索引
                'status'=> $ header ['status'] //状态
            );
            $ ret [] = $ info;
            未设置($头);
        }
        FCLOSE($ ZIP);
        返回$ ret;
    }
    
    
    // ------------------------------------------------ ------ //
    //#获取压缩文件的注释
    //
    // $ archive = new PHPZip();
    // echo $ archive-> GetZipComment(ZIP压缩文件名);
    // ------------------------------------------------ ------ //
    公共函数GetZipComment($ zipfile)
    {
        $ zip = @fopen($ zipfile,'rb');
        如果(!$ zip){return(0); }
        $ centd = $ this-> ReadCentralDir($ zip,$ zipfile);
        FCLOSE($ ZIP);
        返回$ centd [comment];
    }
}

猜你喜欢

转载自blog.csdn.net/dandan520520/article/details/80197669