2013-05-12 32 views
5

Tôi muốn nén (trên bay) một thư mục ở định dạng tar.gz bằng cách sử dụng PHP. Tôi biết nó có thể được thực hiện với exec hoặc sử dụng this code (sử dụng định dạng ZIP) nhưng máy chủ của tôi không hỗ trợ exec và chưa cài đặt phần mở rộng zip của PHP.Nén thư mục ở định dạng tar.gz bằng cách sử dụng PHP

Sau khi tìm kiếm trên Internet Tôi đã xem qua 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); 
?> 

này không làm việc cho nhiều file sử dụng này:

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); 

Trong backup.tar.gz hiện nay có 2 file (test.txttest2.txt).

Nhưng làm cách nào tôi có thể sử dụng điều này để tải xuống một thư mục (và các thư mục con)?

thư của tôi là một cái gì đó như thế này:

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

Trả lời

5

Bạn cần quá liệt kê tất cả các file và thư mục bên trong thư mục bạn muốn nén. Có một hàm liệt kê thư mục đệ quy here. Tôi nghĩ rằng kết hợp mã của bạn với mã của mình với công việc. một cái gì đó như thế này:

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); 
} 

Nó hoạt động tốt cho tôi. Đó là đóng góp đầu tiên của tôi, hy vọng nó giúp ..

+0

Tôi đã sử dụng một khung php để kiểm tra, để 'trả lại' ở dòng cuối cùng có thể không cần thiết .. –

+0

Cảm ơn! Nhưng khi có một thư mục con ('home/Another_Dir/Sub_Dir /'), anh ta chuyển thư mục tới ('home/Sub_Dir /') trong tệp 'backup.tar.gz' và anh ta không duy trì định dạng thư mục thông thường ('home/Another_Dir/Sub_Dir /'). Điều đó có thể được sửa? – user1480019

+1

@GerritHoekstra Tôi đã chỉnh sửa mã để được khắc phục ngay bây giờ. –

Các vấn đề liên quan