首页 > php代码 > php实现文件压缩

php实现文件压缩

<?php

/*

--------------------------

Copyright by T.muqiao(39号天堂桥)

本程序仅供学习讨论使用,在未通知作者作为任何商业用途

         视为中华人民共和国不道德公民

联系方式:442536278@qq.com

-------------------------*/


class ZipAllFloder{

    //压缩文件夹

    

    var $datasec      = array();

    var $ctrl_dir     = array();

    var $eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";

    var $old_offset   = 0; 

    var $dirs         = array(".","");

    var $dirlen       = 0;

    

    function IniVars(){//初始化变量

        $this -> datasec      = array();

        $this -> ctrl_dir     = array();

        $this -> eof_ctrl_dir = "\x50\x4b\x05\x06\x00\x00\x00\x00";

        $this -> old_offset   = 0;

        $this -> dirs         = array(".","");

        $this -> dirlen       = 0;

    }

    

    function ZipFolder($dir,$zipfilename){//压缩一个文件夹 

        if(substr($dir,-1)!="/"){

        $dir .= "/";

    }

    

    $this -> dirlen = strlen($dir); 

        $this -> AddFolderContent($dir);

        $out = $this -> get_file();

        $this -> IniVars();

        $fp = fopen($zipfilename,"w");  

        fwrite($fp,$out,strlen($out));  

        fclose($fp);

    }

    

    function AddFolderContent($dir){//添加文件夹中文件内容

        if(is_dir($dir)){

            $folder = substr($dir,$this ->dirlen);

            if(!in_array($folder,$this->dirs)){

                $this->add_Dir($folder);

            }

            $handle = opendir($dir);

            while($files = readdir($handle)){

                if (($files==".")||($files=="..")) continue; 

                if(is_dir($dir.$files)){

                    $this->AddFolderContent($dir.$files."/");

                }else{

                    $fp = fopen ($dir.$files,"r");

                    $content = @fread ($fp,filesize($dir.$files));  

                    fclose ($fp);  

                    $this->add_File($content,$folder.$files);

                }

            }  

            closedir($handle);

        }

    }

    

    function get_file(){//获得压缩文件数据

        $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 add_dir($name){

        $name   = str_replace("\\", "/", $name); 

        $fr     = "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";

        $fr    .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 

        $fr    .= pack("v", 0 ).$name.pack("V", 0).pack("V", 0).pack("V", 0); 

        $this -> datasec[] = $fr;

        $new_offset = strlen(implode("", $this->datasec)); 

        $cdrec = "\x50\x4b\x01\x02\x00\x00\x0a\x00\x00\x00\x00\x00\x00\x00\x00\x00";

        $cdrec .= pack("V",0).pack("V",0).pack("V",0).pack("v", strlen($name) ); 

        $cdrec .= pack("v", 0 ).pack("v", 0 ).pack("v", 0 ).pack("v", 0 ); 

        $ext = "\xff\xff\xff\xff";

        $cdrec .= pack("V", 16 ).pack("V", $this -> old_offset ).$name; 

        $this -> ctrl_dir[] = $cdrec; 

        $this -> old_offset = $new_offset; 

        $this -> dirs[] = $name;

    }

    

    function add_File($data, $name, $compact = 1){

        $name     = str_replace("\\", "/", $name);

        $dtime    = dechex($this->DosTime());

        $hexdtime = '\x' . $dtime[6] . $dtime[7].'\x'.$dtime[4] . $dtime[5] . '\x' . $dtime[2] . $dtime[3].'\x'.$dtime[0].$dtime[1];

        eval('$hexdtime = "' . $hexdtime . '";');

        if($compact){

            $fr = "\x50\x4b\x03\x04\x14\x00\x00\x00\x08\x00".$hexdtime;

        }else{

            "\x50\x4b\x03\x04\x0a\x00\x00\x00\x00\x00".$hexdtime;

        }

        $unc_len = strlen($data); $crc = crc32($data);

        if($compact){

            $zdata = gzcompress($data); $c_len = strlen($zdata);

            $zdata = substr(substr($zdata, 0, strlen($zdata) - 4), 2);

        }else{

            $zdata = $data;

        }

        $c_len=strlen($zdata);

        $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);

        $fr .= pack('v', strlen($name)).pack('v', 0).$name.$zdata;

        $fr .= pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);

        $this -> datasec[] = $fr;

        $new_offset        = strlen(implode('', $this->datasec));

        if($compact){

            $cdrec = "\x50\x4b\x01\x02\x00\x00\x14\x00\x00\x00\x08\x00";

        }else{ 

            $cdrec = "\x50\x4b\x01\x02\x14\x00\x0a\x00\x00\x00\x00\x00";

        }

        $cdrec .= $hexdtime.pack('V', $crc).pack('V', $c_len).pack('V', $unc_len);

        $cdrec .= pack('v', strlen($name) ).pack('v', 0 ).pack('v', 0 );

        $cdrec .= pack('v', 0 ).pack('v', 0 ).pack('V', 32 );

        $cdrec .= pack('V', $this -> old_offset );

        $this -> old_offset = $new_offset;

        $cdrec .= $name;

        $this -> ctrl_dir[] = $cdrec;

        return true;

    }

    

    function DosTime() {

        $timearray = getdate();

        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);

    }

}



class UnCompress{

    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<$centd['entries']; $i++){

            $header                  = $this->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 Extract($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<$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);

        return $stat;

    }

 

    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 < 277){ 

            $maximum_size = $size;

        }else{ 

            $maximum_size=277;

        }

        @fseek($zip, $size-$maximum_size);

        $pos = ftell($zip); 

        $bytes = 0x00000000;

        while ($pos < $size){

        $byte = @fread($zip, 1); $bytes=($bytes << 8) | Ord($byte);

        if ($bytes == 0x504b0506){ 

            $pos++; 

            break; 

        } 

            $pos++;

        }

        $data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size',

        fread($zip, 18));

        if ($data['comment_size'] != 0){

            $centd['comment'] = fread($zip, $data['comment_size']);

        }else{ 

            $centd['comment'] = ''; $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'];

        return $centd;

    }

 

    function ExtractFile($header,$to,$zip){

        $header = $this->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;

            }

            if(!is_dir($to.$pth[$i])){ 

                @mkdir($to.$pth[$i],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 < 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']);

            }else{

                $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'];

                while ($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') or die("Cette archive est compress");

                if(!$gzp){ 

                    return(-2);

                }

                $fp = @fopen($to.$header['filename'],'wb');

                if(!$fp){ 

                    return(-1);

                }

                $size = $header['size'];

                while ($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($gzp);

                touch($to.$header['filename'], $header['mtime']);

                @unlink($to.$header['filename'].'.gz');

            }

        }

        return true;

    }

}


//统计文件夹内容

class StatFolder{

    var $Num       = 0;

    var $Size      = 0;

    var $TypeNum   = 0;

    var $FolderNum = 0;

    var $Type      = array();

    function __construct($folder){

        $this -> ReadFolder($folder);

    }

    function StatFolder($folder){

        $this -> ReadFolder($folder);

    }

    function ReadFolder($folder){

        if(is_dir($folder)){

        $handle = opendir($folder);

            while($files = readdir($handle)){

                if (($files==".")||($files=="..")) continue; 

                if(is_dir($folder."/".$files)){

        $this ->FolderNum++;

                    $this ->ReadFolder($folder."/".$files);

                }else{

                    $this ->Num++;

                    $type = fileext($files);

                    if(!in_array($type,$this ->Type)){

                    $this ->Type[] = $type;

                    $this ->TypeNum++;

                    }

                                $size = filesize($folder."/".$files);  

                                $this->Size +=$size;

                    clearstatcache();

                }

            }  

            closedir($handle);

        }

    }

    function GetFileNum(){

        return $this -> Num;

    }

    function GetTotalSize(){

        $switch = $this->Size/1024;

        if($switch<1024){

            $return = explode(".",$switch);

            if($return[0]==0){

                return $this->Size." bytes";

            }

            return $return[0].".".substr($return[1],0,3)." Kbytes";

        }else{

            $switch /=1024;

            $return = explode(".",$switch);

            return $return[0].".".substr($return[1],0,3)." Mbytes";

        }

    }

    function GetTypeNum(){

        return $this -> TypeNum;

    }

    function GetFolderNum(){

        return $this -> FolderNum;

    }

}


//检查$testpath是否数学上的属于$reference参照路径 

function matchpath($reference,$testpath){

    $reference = explode("/",$reference);

    $testpath  = explode("/",$testpath);

    $num1 = count($reference);

    $num2 = count($testpath);

    if($num1 < $num2){

        return false;

    }

    $degree = 0;

    for($i=0;$i<$num2;$i++){

        if(strtolower($testpath[$i])==strtolower($reference[$i])){

            $degree++;

            continue;

        }else{

            return false;

            break;

        }

    }

    if($degree==$num2){

        return true;

    }

}


function checkcore($path){//检查核心文件是否包含其中

    global $T_corefile;

    for($i=0;$p=$T_corefile[$i];$i++){

        if(matchpath($p, $path)){

            return true;

            break;

        }

    }

}


function copypath($source,$target,$uncover=true){//拷贝整个目录   默认不允许覆盖

    global $T_lang;

    if(is_dir($target)){

        if($uncover){

            $errors .= str_replace("--replace--",$target,$T_lang['func'][0]);

            $gocover = false;

        }else{

            $gocover = true;

        }

        }else{

            if(matchpath($target,$source)){//检测目录$source是否包含于$target

                $errors .= str_replace("--replace--",$source,$T_lang['func'][1]);

                $gocover = false;

            }else{

                if(@mkdir($target,0777)){

                $gocover = true;

                }else{

                $errors .= str_replace("--replace--",$target,$T_lang['func'][2]);

                $gocover = false;

                }

            }

        }

        if($gocover){

            $handle = opendir($source);

            while($file = readdir($handle)){

                clearstatcache();

                if(substr($file,-1)=="."||substr($file,-2)=="..") continue;

                if(is_dir($source."/".$file)){

                    $errors .= copypath($source."/".$file,$target."/".$file,$uncover);

                }else{

                    $gocopy = true;

                    if(file_exists($target."/".$file)){

                        if($uncover){

                            $gocopy = false;

                        }else{

                            if(@unlink($target."/".$file)){

                                $gocopy = true;

                            }else{

                                $gocopy = false;

                            }

                        }

                    }

                    if($gocopy){

                        if(@copy($source."/".$file,$target."/".$file)){

                            $errors .= "";

                        }else{

                            $errors .= str_replace("--replace--",$source."/".$file,$T_lang['func'][3]);

                        }

                    }else{

                        $errors .= str_replace("--replace--",$target."/".$file,$T_lang['func'][4]);

                    }

                }

            }

            closedir($handle);

        }

        if($errors){

            return $errors;

        }else{

            return "";

        }

    }

    

    function movepath($source,$target,$uncover=true){//移动整个目录  默认不允许覆盖

        global $T_lang;

        if(is_dir($target)){

            if($uncover){

            $errors .= str_replace("--replace--",$target,$T_lang['func'][0]);

            $gocover = false;

            }else{

            $gocover = true;

            }

        }else{

            if(matchpath($target,$source)){//检测目录$source是否包含于$target

                $errors .= str_replace("--replace--",$source,$T_lang['func'][5]);

                $gocover = false;

            }else{

                if(@mkdir($target,0777)){

                    $gocover = true;

                }else{

                    $errors .= str_replace("--replace--",$target,$T_lang['func'][2]);

                    $gocover = false;

                }

            }

        }

        if($gocover){

            $handle = opendir($source);

            while($file = readdir($handle)){

                clearstatcache();

                if(substr($file,-1)=="."||substr($file,-2)=="..") continue;

                if(!is_dir($source."/".$file)){

                    $gocopy = true;

                    if(file_exists($target."/".$file)){

                        if($uncover){

                            $gocopy = false;

                        }else{

                            $gocopy = true;

                        }

                    }

                    if($gocopy){

                        if(@copy($source."/".$file,$target."/".$file)){

                            unlink($source."/".$file);

                        }else{

                            $errors .= str_replace("--replace--",$source."/".$file,$T_lang['func'][3]);

                        }

                    }else{

                        $errors .= str_replace("--replace--",$target."/".$file,$T_lang['func'][6]);

                    }

                }else{

                    $errors .= movepath($source."/".$file,$target."/".$file,$uncover);

                }

            }

            closedir($handle);

        }

        if($errors){

            return $errors;

        }else{

            if(@rmdir($source."/".$file)){

                return "";

            }else{

                $errors .= str_replace("--replace--",$source,$T_lang['func'][7]);

            }

        }

    }

    

    function delpath($source){//删除整个目录

        global $T_lang,$T_Recycled;

        $handle = opendir($source);

        while($file = readdir($handle)){

            clearstatcache();

            if(substr($file,-1)=="."||substr($file,-2)=="..") continue;

            if(is_dir($source."/".$file)){

                $errors .= delpath($source."/".$file);

            }else{

                if(@unlink($source."/".$file)){

                }else{

                    $errors .= str_replace("--replace--",$source,$T_lang['func'][7]);

                }   

            }

        }

        closedir($handle);

        if($errors){

            $errors .= str_replace("--replace--",$source,$T_lang['func'][8]);

            return $errors;

        }else{

            if($source==$T_Recycled){//清空回收站时 这个判断条件用的上

                return "";

            }else{

                if(@rmdir($source)){

                    return "";

                }else{

                    $errors .= str_replace("--replace--",$source,$T_lang['func'][8]);

                    return $errors;

                }  

            }

        }

    }

    

    function limitname($title,$limitlength =13){//限制标题长度

        $length = strlen($title);

        if($length>$limitlength){

            $gbk = 0;

            for($i=0;$i<$limitlength-1;$i++){

                $temp = substr($title,$i,1);

                if(ord($temp)>127) $gbk +=1;

            }

            if($gbk%2){

                $title = substr($title,0,$limitlength)."...";

            }else{

                $title = substr($title,0,$limitlength-1)."...";

            }

        }

        return $title;

    }

    

    function fileext($filename){

        return trim(substr(strrchr($filename, '.'), 1));

    }

    

    function checkpath($path){//检查path合法和合格性

        $path = eregi_replace("root",".",$path);

         if($path=="."||ereg("^(\.\/).*[^\.\/]$",$path)){

             if(eregi("\.\/(.*)?(\.\.\/)+.",$path)){

                return false;

            }else{

                if(is_dir($path)){

                    return $path;

                }else{

                    return false;

                }

            }

        }else{

            return false;

        }

    }

    

    function historypath(){//历史路径

        global $path,$T_rlength,$T_images,$T_main,$T_Recycled;

        $ruote = explode("/",$path);

        $num   = count($ruote);

        if($num<=1){

            return false;

        }else{

            if($num-1>$T_rlength){

                $i = $num-$T_rlength;

            }else{

                $i = 1;

            }

            for(;$i<=$num-1;$i++){

                $rs .= "<img src={$T_images}/direct.gif align=absmiddle><a href=\"{$T_main}?path=";

                $single = ".";

                for($j=1;$j<=$i;$j++){

                $single .= "/".$ruote[$j];

                }

                $rs .= urlencode($single)."\"><img src=\"";

                if($single==$T_Recycled){

                    $rs .= $T_images."/Recycled.gif";

                }else{

                    $rs .= $T_images."/folder.gif";

                }

                $rs .= "\" height=\"50\" width=\"50\" align=absmiddle>".limitname($ruote[$i])."</a>";

            }

            return $rs;

        }

    }

?>


文章地址:http://www.phprm.com/code/16db63b02c1d08460c05c1ef62642a94.html

转载随意^^请带上本文地址!

标签:none

发表留言