php如何优雅的压缩多个文件夹

前言

因为本人写的插件和主题需要热更新,后台发布新版本时需要先打包文件再发布,有的应用更新不是用zba文件而是直接打包成zip文件。

这样打包难免会需要排除一些属于自己网站的文件,或者说是一些静态文件。静态文件不需要每次都发布出去,比如layui的框架。

之前写的打包代码,都是草草了事,能实现文件排除就行。今天迁移演示站,正好需要改动打包行为,所以直接写一个类。

作用

  1. 可以添加多个文件夹 或 文件,然后一起打包在一个zip文件内。

  2. 可以选择性保留原文件夹(原文件夹?)

  3. 可以排除文件夹或文件

用法

$zip = new ZipPackage();  //新建这个对象

$zip->without = 'config.php';  //排除的文件
$zip->without = 'static/layui';  //排除的文件夹
$zip->without = 'static/css/main.css';  //排除的文件 这样的排除方式可以写很多

$zip->source = '/www/zb_users/plugin/LayCenter';  //要压缩的文件夹
$zip->source = '/www/config/data/';  //要压缩的文件夹  (关于文件夹后面添不添加斜杠“/”的问题,请看下面说明)
$zip->source = '/www/.htaccess';  //要压缩的文件  这样的添加方式可以写很多

$zip->zip(dirname(__FILE__).'/1.zip',true);  //开始压缩,第一个参数:zip文件路径   第二个参数:是否覆盖原来的zip文件。传入true 或 false 。默认false,当这个压缩包存在时,就会往里添加文件

压缩的文件夹路径后面的斜杠说明

比如上面要压缩的文件夹     /www/zb_users/plugin/LayCenter

文件夹路径后面没有斜杠: /www/zb_users/plugin/LayCenter          压缩时会先添加LayCenter文件夹,再往这个文件夹内添加压缩内容

文件夹路径后面有斜杠:    /www/zb_users/plugin/LayCenter/         压缩时只会添加这个文件夹下的文件,并不会含有LayCenter这个文件夹

ZipPackage 类

class ZipPackage{
    
    private $filepath = array();
    
    private $withoutarray = array();
    
    private $sourcearray = array();
    
    private $newzip;
    
    public function __set($name,$value){
        
        switch ($name) {
            
            case 'without':
                $this->withoutarray[] = $value;
            break;
            
            case 'source':
                $this->sourcearray[] = $value;
            break;
            
        }
        
    }
    
    private function getdirlist( $dir , $sourcepath , $withfolder){
        
        foreach (scandir($dir) as $v) {
            
            if ($v == '.' || $v == '..') continue;
            
            $inzippath = str_replace( $sourcepath , '' , $dir.$v );
            
            if (in_array($inzippath,$this->withoutarray)) continue;
            
            if (is_dir($dir.$v)){
                
                $this->getdirlist( $dir . $v . '/' , $sourcepath , $withfolder);
                
            }else{
                
                $this->filepath[] = array( 'fullpath' => $dir . $v , 'inzippath' => ($withfolder ? '' : (basename($sourcepath).'/')).$inzippath );
                
            }
        }
        
    }
    
    public function zip($file , $overwrite = false){
        
        $this->newzip = $file;
        
        if (!is_file($file) && $overwrite === true) $overwrite = false;
        
        foreach ($this->sourcearray as $source) {
            
            if (is_dir($source)){
                
                $csource = preg_replace('/\/$/','',$source);
                
                $this->getdirlist( $csource . '/' , $csource . '/' , preg_match('/\/$/',$source));
                
            }elseif (is_file($source)){
                
                $this->filepath[] = array( 'fullpath' => $source , 'inzippath' => basename($source) );
                
            }
            
        }
        
        return $this->compress($overwrite);
        
    }
    
    private function compress($overwrite){
        
        $zip = new ZipArchive();
        
        if ($zip->open($this->newzip, $overwrite ? ZipArchive::OVERWRITE : ZipArchive::CREATE) === true){
            
            foreach ($this->filepath as $v) {
                
                $zip->addFile($v['fullpath'],$v['inzippath']);
                
            }
            
            $zip->close();
            
            if (is_readable($this->newzip)) return true;
            
        }
        
        return false;
        
    }

}