使用PHP压缩tar.gz格式的目录 [英] Compress on the fly a directory in tar.gz format using PHP
问题描述
我想使用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 /
/ pre>
file1.html
file2.html
Another_Dir /
file8.html
Sub_Dir /
file19.html
解决方案您需要列出您要压缩的目录中的所有文件和目录。有一个递归目录列表功能 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 withexec
or usingthis 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
andtest2.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屋!