2012-12-19 66 views
3

我正在嘗試創建一個備份類,其主要目標是定製類調用,以使最終備份僅在特定擴展上進行過濾文件大小或主目錄內的特定目錄,這取決於用戶的選擇。從文件和文件夾的結構化陣列創建ZIP/RAR/GZ存檔

目前,該課程缺乏壓縮算法,因爲我一直在尋找關於.zip壓縮的解決方案。

這裏是一個類將使用能夠創建一個壓縮歸檔的文件和文件夾結構的示例(ZIP,RAR,GZ,等等):

Array 
(
    [0] => pclzip.lib.php 
    [1] => index.php 
    [style] => Array 
     (
      [js] => Array 
       (
        [0] => jNice.js 
        [1] => jquery.js 
       ) 

      [img] => Array 
       (
        [0] => input-shaddow-hover.gif 
        [1] => btn_right.gif 
        [2] => top-menu-bg.gif 
        [3] => top-menu-item-bg.gif 
        [4] => left-menu-bg.gif 
        [5] => button-submit.gif 
        [6] => btn_left.gif 
        [7] => select_right.gif 
        [8] => select_left.gif 
        [9] => transdmin-light.png 
        [10] => content.gif 
        [11] => input-shaddow.gif 
       ) 

      [css] => Array 
       (
        [0] => transdmin.css 
        [1] => layout.css 
        [2] => ie7.css 
        [3] => hack.css 
        [4] => jNice.css 
        [5] => ie6.css 
        [6] => reset.css 
       ) 

     ) 

    [2] => config.php 
    [3] => delete.php 
    [4] => restore.php 
    [5] => cron.php 
    [6] => manage.php 
) 

正如你可以看到,文件並且需要在備份文件中保留文件夾結構,所以要備份的文件和文件夾的列表已經被構建,以便如果數組葉子包含子數組,葉子是目錄,如果葉子不包含子數組,數組,葉是一個FILE。

這就是我來到了在遞歸Zip文件和文件夾的創建過程,(應)的結構數組我介紹工作之前:

private function zipFileAndFolderStructureArray ($backupContentsArray, $zipDestination, $backupRootDirectory) { 
    if ($this -> zipObject == null) { 
     if (extension_loaded ('zip') === true) { 
      $this -> zipObject = new ZipArchive(); 
      if (($zipErrorCode = $this -> zipObject -> open ($zipDestination, ZipArchive::CREATE)) !== true) $this -> zipObject = null; 
      else $this -> zipFileAndFolderStructureArray ($backupContentsArray, $zipDestination, $backupRootDirectory); 
     } 
    } 
    else if ($this -> zipObject != null) { 
     foreach ($backupContentsArray as $folder => $file_or_folder_list) { 
      $cwd = rtrim ($backupRootDirectory, '/') . '/' . $folder . '/'; 
      if (is_array ($file_or_folder_list) && is_dir ($cwd . $folder)) { 
       echo 'adding folder ' . $folder . ' in cwd ' . $cwd . '<br>'; 
       $this -> zipObject -> addEmptyDir ($folder); 
       $this -> zipFileAndFolderStructureArray ($file_or_folder_list, $zipDestination, $cwd); 
      } 
      else if (is_file ($cwd . $file_or_folder_list)) { 
       echo 'adding file ' . $file_or_folder_list . '<br>'; 
       $this -> zipObject -> addFromString ($cwd . $file_or_folder_list); 
      } 
     } 

     $this -> zipObject -> close(); 
     return true; 
    } 
} 

的問題是,我被堵在這一點上。此遞歸函數在輸入第一個文件夾葉後存在,創建一個只有一個空文件夾的歸檔文件。

你能幫我弄清楚有什麼問題嗎?

關於可用類的提示我可以使用它來將壓縮功能擴展到RAR和GZ,儘可能重用ZIP壓縮算法所使用的相同壓縮算法?

預先感謝您

PS補充說,創建文件夾和目錄結構

public function directory_list ($directory_base_path, $filter_dir = false, $filter_files = false, $exclude_empty_dirs = true, $include_extensions = null, $exclude_extensions = null, $exclude_files = null, $recursive = true) { 
    $directory_base_path = rtrim ($directory_base_path, "/") . "/"; 
    if (! is_dir ($directory_base_path)) return false; 

    $result_list = array(); 
    if (! is_array ($exclude_files)) $exclude_array = Array ('.', '..'); 
    else $exclude_array = array_merge (Array ('.', '..'), $exclude_files); 

    if (! $folder_handle = opendir ($directory_base_path)) return false; 
    else{ 
     while (false !== ($filename = readdir ($folder_handle))) { 
      if (! in_array ($filename, $exclude_array)) { 
       if (is_dir ($directory_base_path . $filename . "/")) { 
        if ($recursive && strcmp ($filename, ".") != 0 && strcmp ($filename, "..") != 0) { // prevent infinite recursion 
         $result = self::directory_list("$directory_base_path$filename/", $filter_dir, $filter_files, $exclude_empty_dirs, $include_extensions, $exclude_extensions, $exclude_files, $recursive); 
         if ($exclude_empty_dirs) { 
          if (count (array_keys ($result)) > 0) $result_list[$filename] = $result; 
         } 
         else $result_list[$filename] = $result; 
        } 
        else if (! $filter_dir) $result_list[] = $filename; 
       } 
       else if (! $filter_files) { 
        $extension = end (explode ('.', $filename)); 
        if (! is_array ($include_extensions) && count ($include_extensions) == 0 && ! is_array ($exclude_extensions) && count ($exclude_extensions) == 0) if ($filename != '.' && $filename != '..') $result_list[] = $filename; 
        if (is_array ($exclude_extensions) && count ($exclude_extensions) > 0 && ! in_array ($extension, $exclude_extensions)) $result_list[] = $filename; 
        else if (is_array ($include_extensions) && count ($include_extensions) > 0 && strlen ($extension) > 0 && in_array ($extension, $include_extensions)) $result_list[] = $filename; 
       } 
      } 
     } 
     closedir($folder_handle); 
     return $result_list; 
    } 
} 
+0

的一個固定的版本?這聽起來像[RecursiveDirectoryIterator](http://php.net/class.recursivedireiteiterator)的工作。這是一個5.3的東西,雖然手冊錯誤地說它是5.0的東西。 – Charles

+0

目前在5.3.3上運行 我見過很多使用RecursiveDirectoryIterator的目錄結構創建者的例子,但是想要保持與舊版本的PHP兼容,因爲我想在完成後將這個類分享給公衆。 所以我想出了一個不同的目錄結構創建者使用「較老的方法」過程(我已經在上面的問題中添加了底部) – Maurizio

+0

鑑於PHP維護者已經放棄了對5.3之前的所有內容的支持, 5.5即將到來,不考慮舊版本可能是一件好事,即使有些人不能運行它。 – Charles

回答

1

經調查和迴盪在遞歸壓縮算法,幾乎所有的東西后,當前功能,傳出的文件夾結構很難處理,並需要大量的斜線修復路徑。

這裏是你用什麼在這裏的PHP版本相同zipFileAndFolderStructureArray功能

private function zipFileAndFolderStructureArray ($backupContentsArray, $zipDestination, $backupRootDirectory, $currentWorkingDirectory = '') { 
    if ($this -> zipObject == null) { 
     if (extension_loaded ('zip') === true) { 
      $this -> zipObject = new ZipArchive(); 
      if (($zipErrorCode = $this -> zipObject -> open ($zipDestination, ZipArchive::CREATE)) !== true) $this -> zipObject = '#ERROR#'; 
      else $this -> zipFileAndFolderStructureArray ($backupContentsArray, $zipDestination, $backupRootDirectory); 
     } 
    } 
    else if ($this -> zipObject == '#ERROR#') return false; // return false in case the zipArchive::open returned false on archive opening 
    else { 
     foreach ($backupContentsArray as $folder => $file_or_folder_list) { 
      if (is_array ($file_or_folder_list)) { 
       $current_working_folder = rtrim ($currentWorkingDirectory, '/') . '/' . $folder . '/'; 
       if (is_dir ($backupRootDirectory . $current_working_folder)) { 
        // not necessary to add an empty folder in this case: the addFile will take care of creating the folder structure in the zip file 
        $this -> zipFileAndFolderStructureArray ($file_or_folder_list, $zipDestination, $backupRootDirectory, rtrim ($current_working_folder, '/')); 
       } 
      } 
      else if (is_file ($backupRootDirectory . trim ($currentWorkingDirectory, '/') . '/' . $file_or_folder_list)) { 
       $file_insertion = $backupRootDirectory . trim ($currentWorkingDirectory, '/') . '/' . $file_or_folder_list; 
       $zip_filename = str_replace ($backupRootDirectory, '', $file_insertion); 
       if (substr_count ($zip_filename, '/') == 1) $zip_filename = trim ($zip_filename, '/'); // file in backup root directory fix 
       $this -> zipObject -> addFile ($file_insertion, $zip_filename); 
      } 
     } 
     return true; 
    } 
} 
相關問題