php如何优雅的压缩多个文件夹
前言
因为本人写的插件和主题需要热更新,后台发布新版本时需要先打包文件再发布,有的应用更新不是用zba文件而是直接打包成zip文件。
这样打包难免会需要排除一些属于自己网站的文件,或者说是一些静态文件。静态文件不需要每次都发布出去,比如layui的框架。
之前写的打包代码,都是草草了事,能实现文件排除就行。今天迁移演示站,正好需要改动打包行为,所以直接写一个类。
作用
-
可以添加多个文件夹 或 文件,然后一起打包在一个zip文件内。
-
可以选择性保留原文件夹(原文件夹?)
-
可以排除文件夹或文件
用法
$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;
}
}