压缩工具类 - base_tar

功能描述

这个类用来处理tar包, 目前不支持gzip压缩

这个类的原作者: Josh Barger <joshb@npt.com>.原类存在两个问题, 因此做了一定程度的改善

  • 在生成tar包时需要将所有文件内容加载至内存,然后一起写入磁盘, 容易造成内存溢出
  • 必须实际文件才可以打tar包. 满足不了业务需求

应用场景

  • 数据备份
  • 模板包

属性

解包时专用属性

filename

待解包文件名

tar_file

待解包文件的文件句柄

公用属性

files

二维数组, 表示tar包内所有文件的信息.

每一行的格式为{$infomation}, 格式为:

    array(
	'name' => $file_name,
	'mode' => $file_mode,
	'size' => $file_size,
	'time' => $file_time,
	'member_id' => $file_uid,
	'group_id' => $file_gid,
	'user_name' => $file_uname,
	'group_name' => $file_gname,
	'checksum' => $file_chksum,
	'offset' => $file_offset
	)

directories

所有目录信息, 二维数组, 格式为{$information}见上文

numFiles

文件数量

numDirectories

目录数量

函数接口

openTAR

打开一个tar包文件

参数:
    string $filename tar包文件名
返回:
    bool 如果成功为true, 反之为false

closeTAR

关闭tar包(关闭文件指针)

参数:
    无
返回:
    bool 如果成功为true, 反之为false

appendTar

同时再打开一个tar包

参数:
    string $filename tar包文件名
返回:
    bool 如果成功为true, 反之为false

getFile

获取tar包内文件的详细信息

参数:
    string $filename tar包文件名
返回:
    array 成功的话返回文件信息一维数组, 格式为{$information}见上文, 失败返回false. 

getContents

从tar包中取出文件内容

参数:
    string $information 格式为{$information}, 见上文
返回:
    string 如果成功则返回文件内容, 反之为false

getDirectory

获取tar包内的目录信息

参数:
    string $dirname 目录名
返回:
    array 如果成功为目录的{$information}, 反之为false

containsFile

判断tar包内是否存在某一文件

参数:
    string $filename 文件名
返回:
    bool 如果成功为目录的{$information}, 反之为false

containsDirectory

判断tar包内是否存在某一目录

参数:
    string $filename 文件名
返回:
    bool 如果成功为true, 反之为false

addDirectory

为tar包增加一个目录

参数:
    string $dirname 目录名
返回:
    bool 如果成功为true, 反之为false

addFile

为tar包增加一个文件

参数:
    string $filename 文件名
    string $file_contents 文件内容. 默认值为false, 如果值为false, 则会到$filename路径取得文件内容
返回:
    bool 如果成功为true, 反之为false

removeFile

从tar包中删除文件

参数:
    string $filename 文件名
返回:
    bool 如果成功为true, 反之为false

removeDirectory

从tar包中删除目录

参数:
    string $filename 文件名
返回:
    bool 如果成功为true, 反之为false

saveTar

将tar包保存至实际文件

参数:
    无
返回:
    bool 如果成功为true, 反之为false

getTar

返回tar文件内容

参数:
    string $type 返回类型, 如果$type为output则直接输出. 默认为output
返回:
    string tar文件内容

toTar

将当前文档保存到另外的tar包文件中

参数:
    string $filename 文件名路径
返回:
    bool 如果成功为true, 反之为false

gzcompressfile

将已有tar包压缩成tar.gz包放在和tar包同级目录下

参数:
    string $source 需要压缩的tar包路径
返回:
    bool 如果成功为true, 反之为false

几个例子

解包 - 安装模板

<?php

$t_dir 
'模板需要放置的绝对路径';
$tar kernel::single('base_tar');
$tar->openTAR($theme_tar_filename) { //打开模板tar包文件
if($tar->containsFile('theme.xml')) { //判断tar包内是否有模板描述文件theme.xml
    
foreach($tar->files as $id => $file) { //循环模板包内的所有文件
        
if(!preg_match('/\.php/',$file['name']) || preg_match('/^widgets\/(.*)\.php$/'$file['name'])){ //只有widges目录下的php会解包并放在相关目录下
             
$fpath $t_dir.$file['name']; //拼接出文件的全路径
             
if(!is_dir(dirname($fpath))){
                 if(
mkdir(dirname($fpath), 0755true)){ //递归建立目录
                     
file_put_contents($fpath,$tar->getContents($file)); //从tar包中取文件数据
                 
}else{
             ...
                 }
             }else{
                 
file_put_contents($fpath,$tar->getContents($file)); //将tar包中的文件解包到实际的目录中.
             
}
         }
     }
     
$tar->closeTAR(); //关闭tar包
     
...
}

打包 -

<?php
 $tar 
kernel::single('base_tar');
 
$workdir getcwd();  //记录当前工作目录

 
if(chdir(THEME_DIR.'/'.$theme)){ //将工作目录切到实际要压缩的位置
     
$this->__get_all_files('.',$aFile);  //取到所有要打包的文件列表, $aFile为引用返回
     
for($i=0;$i<count($aFile);$i++){  
         if(
$f substr($aFile[$i],2)){
             if(
$f!='theme.xml'){
                 
$tar->addFile($f); //向tar包中加文件
             
}
         }
     }
     if(
is_file('info.xml')){
         
$tar->addFile('info.xml',file_get_contents('info.xml'));
     }
     
$tar->addFile('theme.xml',$this->make_configfile($theme));

     ...
     
//取到tar包的实际内容然后通过http输出
     
header("Cache-Control: no-cache, must-revalidate"); // HTTP/1.1
     
header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
     
header('Content-type: application/octet-stream');
     
header('Content-type: application/force-download');
     
header('Content-Disposition: attachment; filename="'.$name.'.tgz"');
     
$tar->getTar('output'); //生成实际的tar包文件, 并且输出 
     
chdir($workdir); //打包完成后切到打包前的工作目录
     
...

}