2012-10-15 104 views
4

我可以使用相對路徑壓縮文件嗎?ZipArchives存儲絕對路徑

例如:

$zip->addFile('c:/wamp/www/foo/file.txt');

的ZIP應該有這樣的目錄結構:

foo 
-> file.txt 

,而不是:

wamp 
-> www 
    -> foo 
     -> file.txt 

像它在默認情況下...

PS:我完整的代碼here(我使用ZipArchive到一個目錄的內容壓縮成zip文件)

回答

8

addFile()函數定義,可以覆蓋存檔文件名:

$zip->addFile('/path/to/index.txt', 'newname.txt'); 
+0

oh tx。我怎樣才能對空目錄做同樣的事情?它看起來像addEmptyDir函數沒有第二個參數? – Alex

+1

只需傳遞新的目的地名稱即可。也就是說,如果你的源代碼是/ path/to/empty,那麼只需調用'$ zip-> addEmptyDir(「empty」);' –

+0

doh :)謝謝:D – Alex

3

如果您嘗試遞歸添加文件夾的所有子文件夾和文件,則可以嘗試下面的代碼(我修改了this code/note in the php manual)。

class Zipper extends ZipArchive { 
    public function addDir($path, $parent_dir = '') { 
     if($parent_dir != ''){ 
      $this->addEmptyDir($parent_dir); 
      $parent_dir .= '/'; 
      print '<br>adding dir ' . $parent_dir . '<br>'; 
     } 
     $nodes = glob($path . '/*'); 
     foreach ($nodes as $node) { 
      if (is_dir($node)) { 
       $this->addDir($node, $parent_dir.basename($node)); 
      } 
      else if (is_file($node)) { 
       $this->addFile($node, $parent_dir.basename($node)); 
       print 'adding file '.$parent_dir.basename($node) . '<br>'; 
      } 
     } 
    } 
} // class Zipper 

所以基本上這樣做是它要壓縮,而是隻從實際文件夾,你想壓縮(相對路徑)開始實際的目錄/文件夾之前不包括目錄(絕對路徑) 。

+0

非常感謝這個作品!比我見過的使用PHP遞歸壓縮當前文件夾的其他代碼片段更好。 – gaborous

+0

實際上,該解決方案不存儲點文件(如.htaccess),因爲GLOB會自動對其進行過濾。 GLOB有一個解決方法,但你也可以使用scandir()或opendir(),它實際上更快。我會在下面發佈一個代碼。 – gaborous

+0

謝謝,請發帖然後我會更新我的答案。 – Paolo

1

這裏是Paolo腳本的修改版本,以便還包含點文件,如.htaccess,並且它應該會更快一些,因爲我替換了glob by opendir as adviced here

<?php 

$password = 'set_a_password'; // password to avoid listing your files to anybody 

if (strcmp(md5($_GET['password']), md5($password))) die(); 

// Make sure the script can handle large folders/files 
ini_set('max_execution_time', 600); 
ini_set('memory_limit','1024M'); 

//path to directory to scan 
if (!empty($_GET['path'])) { 
    $fullpath = realpath($_GET['path']); // append path if set in GET 
} else { // else by default, current directory 
    $fullpath = realpath(dirname(__FILE__)); // current directory where the script resides 
} 

$directory = basename($fullpath); // parent directry name (not fullpath) 
$zipfilepath = $fullpath.'/'.$directory.'_'.date('Y-m-d_His').'.zip'; 

$zip = new Zipper(); 

if ($zip->open($zipfilepath, ZipArchive::CREATE)!==TRUE) { 
    exit("cannot open/create zip <$zipfilepath>\n"); 
} 

$past = time(); 

$zip->addDir($fullpath); 

$zip->close(); 

print("<br /><hr />All done! Zipfile saved into ".$zipfilepath); 
print('<br />Done in '.(time() - $past).' seconds.'); 

class Zipper extends ZipArchive { 

    // Thank's to Paolo for this great snippet: http://stackoverflow.com/a/17440780/1121352 
    // Modified by LRQ3000 
    public function addDir($path, $parent_dir = '') { 
     if($parent_dir != '' and $parent_dir != '.' and $parent_dir != './') { 
      $this->addEmptyDir($parent_dir); 
      $parent_dir .= '/'; 
      print '<br />--> ' . $parent_dir . '<br />'; 
     } 

     $dir = opendir($path); 
     if (empty($dir)) return; // skip if no files in folder 
     while(($node = readdir($dir)) !== false) { 
      if ($node == '.' or $node == '..') continue; // avoid these special directories, but not .htaccess (except with GLOB which anyway do not show dot files) 
      $nodepath = $parent_dir.basename($node); // with opendir 
      if (is_dir($nodepath)) { 
       $this->addDir($nodepath, $parent_dir.basename($node)); 
      } elseif (is_file($nodepath)) { 
       $this->addFile($nodepath, $parent_dir.basename($node)); 
       print $parent_dir.basename($node).'<br />'; 
      } 
     } 
    } 
} // class Zipper 

?> 

這是一個獨立的腳本,只是複製/粘貼到一個PHP文件(如:zipall.php),並在瀏覽器中打開它(如:zipall.php?password=set_a_password,如果您沒有設置正確的密碼,該頁面將保持空白以保證安全)。之後必須使用FTP帳戶來檢索zip文件,這也是一項安全措施。