我想使用PHP以tar.gz
格式压缩(动态)目录。我知道可以使用exec
或使用this code
(使用ZIP格式)来完成,但我的主机不支持exec,并且没有安装PHP的zip扩展名。
在搜索互联网后,我遇到了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);
?>
这适用于使用此文件的多个文件:
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
答案 0 :(得分:5)
您还需要列出要压缩的目录中的所有文件和目录。有一个递归目录列表函数here。我认为将代码与代码结合起来完成工作。像这样的东西:
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);
}
对我来说很好。这是我的第一个贡献,希望它有所帮助..