2014-02-25 93 views
1

試圖獲得導入/導出功能。ZipArchive無法解壓ZipArchive在PHP中拉鍊的文件

  1. 包含一個文件
  2. 使用ZipArchive
  3. 解壓使用ZipArchive
  4. 新文件夾中創建壓縮文件夾郵編PHP中的文件夾中的文件夾,但裏面的文件丟失

    function unArchive(){ 
        $zip = new ZipArchive; 
        $res = $zip->open('zipTest.zip'); 
        if ($res === TRUE) { 
         echo 'ok'; 
         $zip->extractTo("testfolder2"); 
         $zip->close(); 
        } else { 
         echo 'failed, code:' . $res; 
        } 
    } 
    
    function Zip($source, $destination){ 
        if (!extension_loaded('zip') || !file_exists($source)){ 
         return false; 
        } 
        $zip = new ZipArchive(); 
        if (!$zip->open($destination, ZIPARCHIVE::CREATE)) { 
         return false; 
        } 
        $source = str_replace('\\', '/', realpath($source)); 
        if (is_dir($source) === true){ 
    
         $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($source), RecursiveIteratorIterator::SELF_FIRST); 
         foreach ($files as $file){ 
          $file = str_replace('\\', '/', realpath($file)); 
          if (is_dir($file) === true){ 
           $zip->addEmptyDir(str_replace($source . '/', '', $file . '/')); 
          }else if (is_file($file) === true){ 
           $zip->addFromString(str_replace($source . '/', '', $file), file_get_contents($file)); 
          } 
         } 
    
    
        }else if (is_file($source) === true){ 
         $zip->addFromString(basename($source), file_get_contents($source)); 
        } 
        return $zip->close(); 
    } 
    
    Zip("testfolder/" , "./zipTest.zip"); 
    unArchive(); 
    

代碼適用於單個文件。 使用ZipArchive壓縮文件,我可以使用WinRAR手動解壓縮,然後使用WinRAR重新壓縮,然後ZipArchive可以成功解壓縮該文件。 問題是ZipArchive不會提取它直接壓縮的壓縮文件。 我還可以在Notepad ++中看到,ZipArchive zip與WinRAR zip不同,文件大小也不同。我可以成功地將winrar作爲一個系統命令在PHP中調用所需的功能,但這似乎是一個糟糕的主意。 ZipArchive創建無法提取的zip文件是否有某些原因?

錯誤消息:ZipArchive :: extractTo():; 「」 在[文件]參數無效線[$ zip-> extractTo( 「testfolder2」)]

+1

你有沒有得到過這個答案,我在Windows上遇到同樣的問題 – Bren1818

+0

'testfolder2'文件夾已經存在嗎?如果不是,那麼你可能需要先創建一個→if(!file_exist('testfolder2')){mkdir('testfolder2',0777)}' –

回答

0

的RecursiveIteratorIterator返回僞文件這在這裏很重要,「..」 - 父目錄。當您使用addEmptyDir添加父目錄時,ZipArchive會添加它(以某種方式)!你甚至可以嘗試「$ zip-> addEmptyDir(」../ something「)」,它不會抱怨。

現在,通常,zip文件不會以這種方式運行。當您提取它們時,您希望所有內容都位於您提取它們的文件夾中,而不是在父文件夾中。這就是爲什麼普通的ZIP提取程序不能顯示它。

但是,PHP ZipArchive會提取這些文件夾。然後,這個錯誤會以某種方式發生,因爲你試圖包含「。」或「..」目錄。

在的foreach循環的開頭添加這解決此問題:

if (basename($file) === ".") { continue;} 
if (basename($file) === "..") { continue; } 

測試用例:

<?php 
$archive = new ZipArchive(); 
$archive->open('c.zip',ZipArchive::CREATE); 
$archive->addFile('a.txt'); 
$archive->addFile('b.txt'); 
$archive->addEmptyDir("../../down"); 
$archive->close(); 

$archive2 = new ZipArchive(); 
$archive2->open('c.zip'); 
$archive2->extractTo('here'); 
$archive2->close(); 

我測試這個只能在Windows上。