使用PHP压缩tar.gz格式的目录 [英] Compress on the fly a directory in tar.gz format using PHP

查看:180
本文介绍了使用PHP压缩tar.gz格式的目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用PHP压缩(即时)在 tar.gz 格式的目录。我知道可以用 exec 或使用 此代码 (使用ZIP格式),但是我的主机不支持exec,还没有安装zip PHP的扩展。



搜索互联网后,我遇到了 这个PHP代码

 <?php 
//计算文件头的无符号校验和
/ /尝试确保有效的文件
// PRIVATE ACCESS FUNCTION
函数__computeUnsignedChecksum($ bytestring){
for($ i = 0; $ i< 512; $ i ++)
$ unsigned_chksum + = ord($ bytestring [$ i]); ($ i = 0; $ i <8; $ i ++)
$ unsigned_chksum - = ord($ bytestring [148 + $ i]);

$ unsigned_chksum + = ord()* 8;

return $ unsigned_chksum;
}

//从处理的数据生成一个TAR文件
// PRIVATE ACCESS FUNCTION
函数tarSection($ Name,$ Data,$ information = NULL) {
//为此文件生成TAR标头

$ header。= str_pad($ Name,100,chr(0));
$ header。= str_pad(777,7,0,STR_PAD_LEFT)。 CHR(0);
$ header。= str_pad(decoct($ information [user_id]),7,0,STR_PAD_LEFT)。 CHR(0);
$ header。= str_pad(decoct($ information [group_id]),7,0,STR_PAD_LEFT)。 CHR(0);
$ header。= str_pad(decoct(strlen($ Data)),11​​,0,STR_PAD_LEFT)。 CHR(0);
$ header。= str_pad(decoct(time(0)),11​​,0,STR_PAD_LEFT)。 CHR(0);
$ header。= str_repeat(,8);
$ header。=0;
$ header。= str_repeat(chr(0),100);
$ header。= str_pad(ustar,6,chr(32));
$ header。= chr(32)。 CHR(0);
$ header。= str_pad($ information [user_name],32,chr(0));
$ header。= str_pad($ information [group_name],32,chr(0));
$ header。= str_repeat(chr(0),8);
$ header。= str_repeat(chr(0),8);
$ header。= str_repeat(chr(0),155);
$ header。= str_repeat(chr(0),12);

//计算头校验和
$ checksum = str_pad(decoct(__ computeUnsignedChecksum($ header)),6,0,STR_PAD_LEFT); ($ i = 0; $ i< 6; $ i ++){
$ header [(148 + $ i)] = substr($ checksum,$ i,1)

}
$ header [154] = chr(0);
$ header [155] = chr(32);

//填充文件内容到字节计数可分为512
$ file_contents = str_pad($ Data,(ceil(strlen($ Data)/ 512)* 512),chr(0) );

//向tar文件内容添加新的tar格式的数据
$ tar_file = $ header。 $ file_contents;

return $ tar_file;
}

函数targz($ Name,$ Data){
return gzencode(tarSection($ Name,$ Data),9);
}

header(Content-Disposition:attachment; filename = backup.tar.gz);
header(Content-type:application / x-gzip);

$ getfile = file_get_contents(test.txt);

echo targz('test.txt',$ getfile);
?>

这可以使用以下方式处理多个文件:

  header(Content-Disposition:attachment; filename = backup.tar.gz); 
header(Content-type:application / x-gzip);

$ getfile = file_get_contents(test.txt);

echo targz('test.txt',$ getfile);

$ getfile2 = file_get_contents(test2.txt);

echo targz('test2.txt',$ getfile2);

backup.tar.gz 中现在有2个文件( test.txt test2.txt )。



但是如何使用它来下载目录(和子目录)?



我的目录是这样的:

  home / 
file1.html
file2.html
Another_Dir /
file8.html
Sub_Dir /
file19.html
/ pre>

解决方案

您需要列出您要压缩的目录中的所有文件和目录。有一个递归目录列表功能 here 。我想结合你的代码与他的代码做的工作。如下所示:

  header(Content-Disposition:attachment; filename = backup.tar.gz); 
header(Content-type:application / x-gzip);

//您的其他tar.gz函数...

函数compress($ path ='。',$ level = 0){
$ ignore = array('cgi-bin','。','..');
$ dh = @opendir($ path);

while(false!==($ file = readdir($ dh))){
if(!in_array($ file,$ ignore)){
if(is_dir ($ path / $ file)){
//转到subdirs压缩subdirs
compress($ path / $ file,($ level + 1))内的文件);
} else {
$ getfile = file_get_contents($ path。'/'。$ file);
//获取路径
$ dirs = array_filter(explode('/',$ path))中的最后一个目录);
$ dir = array_pop($ dirs);

//如果我们不在一个子目录中,只需压缩该文件,否则将其添加到子目录...
if($ level< 1){
echo targz($ file,$ getfile);
} else {
//当$ level为>时,添加所有顶级子目录2
($ i = 0; $ i <$ level - 1; $ i ++){
$ temp = array_pop($ dirs);
$ dir = $ temp。'/'。$ dir;
}
echo targz($ dir。'/'。$ file,$ getfile);
}
}
}
}

closedir($ dh);
}

$ dir ='dir / to / compress';
if(is_file($ dir)){
//如果它是一个文件路径,只需压缩它&推送它输出
$ getfile = file_get_contents($ dir);
echo targz(basename($ dir),$ getfile);
} elseif(is_dir($ dir)){
return compress($ dir);
}

这对我来说很好。这是我的第一个贡献,希望它有帮助..


I want to compress (on the fly) a directory in tar.gz format using PHP. I know it can be done with exec or using this code (using ZIP format) but my host doesn't support exec and hasn't installed the zip extension of PHP.

After searching the internet I came across this PHP code:

<?php
// Computes the unsigned Checksum of a file’s header
// to try to ensure valid file
// PRIVATE ACCESS FUNCTION
function __computeUnsignedChecksum($bytestring) {
  for($i=0; $i<512; $i++)
    $unsigned_chksum += ord($bytestring[$i]);
  for($i=0; $i<8; $i++)
    $unsigned_chksum -= ord($bytestring[148 + $i]);
  $unsigned_chksum += ord(" ") * 8;

  return $unsigned_chksum;
}

// Generates a TAR file from the processed data
// PRIVATE ACCESS FUNCTION
function tarSection($Name, $Data, $information=NULL) {
  // Generate the TAR header for this file

  $header .= str_pad($Name,100,chr(0));
  $header .= str_pad("777",7,"0",STR_PAD_LEFT) . chr(0);
  $header .= str_pad(decoct($information["user_id"]),7,"0",STR_PAD_LEFT) . chr(0);
  $header .= str_pad(decoct($information["group_id"]),7,"0",STR_PAD_LEFT) . chr(0);
  $header .= str_pad(decoct(strlen($Data)),11,"0",STR_PAD_LEFT) . chr(0);
  $header .= str_pad(decoct(time(0)),11,"0",STR_PAD_LEFT) . chr(0);
  $header .= str_repeat(" ",8);
  $header .= "0";
  $header .= str_repeat(chr(0),100);
  $header .= str_pad("ustar",6,chr(32));
  $header .= chr(32) . chr(0);
  $header .= str_pad($information["user_name"],32,chr(0));
  $header .= str_pad($information["group_name"],32,chr(0));
  $header .= str_repeat(chr(0),8);
  $header .= str_repeat(chr(0),8);
  $header .= str_repeat(chr(0),155);
  $header .= str_repeat(chr(0),12);

  // Compute header checksum
  $checksum = str_pad(decoct(__computeUnsignedChecksum($header)),6,"0",STR_PAD_LEFT);
  for($i=0; $i<6; $i++) {
    $header[(148 + $i)] = substr($checksum,$i,1);
  }
  $header[154] = chr(0);
  $header[155] = chr(32);

  // Pad file contents to byte count divisible by 512
  $file_contents = str_pad($Data,(ceil(strlen($Data) / 512) * 512),chr(0));

  // Add new tar formatted data to tar file contents
  $tar_file = $header . $file_contents;

  return $tar_file;
}

function targz($Name, $Data) {
  return gzencode(tarSection($Name,$Data),9);
}

header("Content-Disposition: attachment; filename=backup.tar.gz");
header("Content-type: application/x-gzip");

$getfile = file_get_contents("test.txt");

echo targz('test.txt', $getfile);
?>

This does work for multiple files using this:

header("Content-Disposition: attachment; filename=backup.tar.gz");
header("Content-type: application/x-gzip");

$getfile = file_get_contents("test.txt");

echo targz('test.txt', $getfile);

$getfile2 = file_get_contents("test2.txt");

echo targz('test2.txt', $getfile2);

In the backup.tar.gz are now 2 files (test.txt and test2.txt).

But how can I use this to download a directory (and the sub directories)?

My directory is something like this:

home/
    file1.html
    file2.html
Another_Dir/
    file8.html
    Sub_Dir/
        file19.html

解决方案

You need too list all files and directory inside the directory you want to compress. There's a recursive directory listing function here. I think combining your code with his code with do the work. something like this:

header("Content-Disposition: attachment; filename=backup.tar.gz");
header("Content-type: application/x-gzip");

// Your other tar.gz functions...

function compress( $path = '.', $level = 0 ){ 
    $ignore = array( 'cgi-bin', '.', '..' ); 
    $dh = @opendir( $path );

    while( false !== ( $file = readdir( $dh ) ) ){                                   
        if( !in_array( $file, $ignore ) ){
            if( is_dir( "$path/$file" ) ){
                // Go to the subdirs to compress files inside the subdirs
                compress( "$path/$file", ($level+1) );                                           
            } else {
                $getfile = file_get_contents($path. '/' .$file);
                // get the last dir in the $path
                $dirs = array_filter( explode('/', $path) );
                $dir = array_pop($dirs);

                // if we're not in a sub dir just compress the file in root otherwise add it on the subdir...
                if ($level < 1) {
                    echo targz($file, $getfile);
                } else {
                    // add all top level subdirs when $level is > 2
                    for ($i = 0; $i < $level - 1; $i++) {
                        $temp = array_pop($dirs);
                        $dir = $temp.'/'.$dir;
                    }
                    echo targz($dir. '/' .$file, $getfile);
                }
            }                                        
        }                                    
    } 

    closedir( $dh ); 
}

$dir    = 'dir/to/compress';
if (is_file($dir)) {
    // If it's a file path just compress it & push it to output
    $getfile = file_get_contents($dir);
    echo targz(basename($dir), $getfile);
} elseif(is_dir($dir)) {
    return compress($dir);
}

It works fine for me. It's my first contribution, hope it helps..

这篇关于使用PHP压缩tar.gz格式的目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆