2014-05-05 146 views
0

我有一個已經傳遞給數組的目錄樹。以遞歸方式查找空文件夾並遞歸刪除它們

我想在這個數組裏面有空文件夾。

如何確定空的文件夾,如/wp-content/uploads/2014/02//wp-content/uploads/2014/。 如何遞歸刪除它們。

這裏是我的陣列

array (
    0 => './do-update.php', 
    5 => './wp-config.php', 
    6 => './wp-content/', 
    7 => './wp-content/uploads/', 
    8 => './wp-content/uploads/2013/', 
    9 => './wp-content/uploads/2013/05/', 
    10 => './wp-content/uploads/2013/05/kabeduvarkad-1024x768.jpg', 
    26 => './wp-content/uploads/2013/05/kabeduvarkad2.jpg', 
    27 => './wp-content/uploads/2013/10/', 
    28 => './wp-content/uploads/2014/', 
    29 => './wp-content/uploads/2014/02/', 
    30 => './wp-content/uploads/de.php', 
    31 => './wp-update.tar.gz', 
    32 => './wp-update/', 
    33 => './wp-update/wp-update.tar', 
) 

非常感謝您對Andresch Serj他effords。 誰想要以性能遞歸刪除空文件夾,可以使用此解決方案。

function list_directory($dir) { 
    $file_list = array(); 
    $stack[] = $dir; 

    while ($stack) { 
     $current_dir = array_pop($stack); 
     if ($dh = opendir($current_dir)){ 
      while (($file = readdir($dh)) !== false) { 
       if ($file !== '.' AND $file !== '..') { 
        $current_file = "{$current_dir}/{$file}"; 
        $report = array(); 
        if (is_file($current_file)) { 
         $file_list[] = "{$current_dir}/{$file}"; 
        } elseif (is_dir($current_file)) { 
         $stack[] = $current_file; 
         $file_list[] = "{$current_dir}/{$file}/"; 
        } 
       } 
      } 
     } 
    } 
    sort($file_list, SORT_LOCALE_STRING); 
    return $file_list; 
} 

function remove_emptyfolders($array_filelist){ 
    $files = array(); 
    $folders = array(); 
    foreach($array_filelist as $path){ 
     // better performance for is_dir function 
     if ($path[strlen($path)-1] == '/'){ // check for last character if it is/which is a folder. 
      $folders[] = $path; 
     } 
     else{ 
      $files[] = $path; 
     } 
    } 

    // bos olmayan klasorleri buluyoruz. 
    // eger klasor ismi dosya isimlerinin icerisinde gecmiyorsa bos demektir? right? 
    $folders_notempty = array(); 
    foreach($files as $file){ 
     foreach($folders as $folder){ 
      if(strpos($file,$folder) !== false){ 
       // dublicate olmasin diye key isimlerinin ismine yazdırdık. 
       $folders_notempty[$folder] = $folder; 
      } 
     } 
    } 

    // bos olmayanla klasorleri, digerlerinden cikariyoruz. 
    $folders_empty = array(); 
    foreach($folders as $folder){ 
     // eger bos olmayanlarin icerisinde bu dosya yoksa 
     if(!in_array($folder, $folders_notempty)){ 
      $folders_empty[] = $folder; 
     } 
    } 

    // once en uzaktan silmeye baslamaliyiz. kisaca tersten. 
    $folders_empty = array_reverse($folders_empty); 
    $folders_deleted = array(); 

    foreach($folders_empty as $k){ 
     try{ 
      $folders_deleted[$k] = 'NOT Succesfull'; 
      if(rmdir($k)){ $folders_deleted[$k] = 'Deleted'; continue; } 
      chmod($k, 0777); 
      if(rmdir($k)){ $folders_deleted[$k] = 'Deleted after chmod'; } 
     }catch (Exception $e) { 
      print_r($e); 
     } 
    } 

    return $folders_deleted; 

} 

$files = list_directory(getcwd()); 
//print_r($files); 
$files_deleted = remove_emptyfolders($files); 

print_r($files_deleted); 
+0

1.只需使用phps文件系統函數逐個檢查文件夾,並且2.您不必遞歸刪除,因爲要刪除的文件夾應該是空的,它們不應該是空的嗎? – arkascha

+0

重複的http://stackoverflow.com/questions/1833518/remove-empty-subfolders-with-php –

+0

文森特是正確的,小的差異是識別這種情況下的文件夾的問題。 Andresch Serj用is_dir解決了這個問題。現在的問題是如何刪除它們?因爲當我們嘗試刪除empty1之前empty2/empty1不能被刪除它不是免費的(empty1/empty2) –

回答

0

只需使用foreach迭代您的陣列即可。

foreach ($filesArray as $file) { 

然後爲每個文件,使用scandir檢查它是否是使用is_dir一個文件夾類似這樣的

if (is_dir ($file)) { 

如果它是一個文件夾/目錄,閱讀目錄,instanse。

$directoryContent = scandir($file); 

如果SCANDIR的結果是空的,你有,你可以用unlink刪除一個空文件夾。

if (count($directoryContent) <= 2) { // checkig if there is moire than . and .. 
    unlink($file); 

如果您在使用unlink時遇到問題,則可能需要相應地設置文件權限。

如果您需要一個遞歸刪除給定paht的空子文件夾的函數,則應該考慮讀取SO question that was linkes in the comments

編輯

考慮到您的意見後,你做什麼想要的是刪除父文件夾,以及一個功能。因此,對於geiven level1/level2/level3,其中level3爲空,並且level2中唯一的文件夾/文件也要刪除level2

因此,從您的示例數組中,您希望刪除./wp-content/uploads/2014/,而不僅僅是./wp-content/uploads/2014/10,但前提是./wp-content/uploads/2014/10沒有包含內容的子文件夾或子文件夾。

那麼該怎麼做?

Simle:將您的支票延長到文件夾爲空的天氣。如果它是空的,請處理給定的文件/路徑字符串以獲取父文件夾。現在你應該將這個外包給一個遞歸函數。

function doesDirectoryOnlyContainEmptyFolders($path) { 
    if(is_dir($path) { 
    $directoryContent = scandir($path); 
    if (count($directoryContent) <= 2) { 
     return true; 
    } 
    else { 
     foreach ($directoryContent as $subPath) { 
     if($filePath !== '.' && $filePath !== '..' && !doesDirectoryOnlyContainEmptyFolders($subPath)) { 
      return false; 
     } 
     } 
     return true; 
    } 
    } 
    return false; 
} 

所以這個遞歸函數檢查,如果一個路徑具有含空文件夾只有空文件夾或文件夾 - 遞歸。 現在你想檢查你的路徑,也許刪除它們,遞歸地向下和向上。

function deleteEmptyFoldersRecursivelyUpAndDown($path) { 
    if (is_dir($path)) { 
    if(doesDirectoryOnlyContainEmptyFolders($path)) { 
     unlink($path); 
     $parentFolder = substr($path, 0, strripos ($path, '/')); 
     deleteEmptyFoldersRecursivelyUpAndDown($parentFolder); 
    } 
    else { 
     $directoryContent = scandir($path); 
     foreach ($directoryContent as $subPath) { 
     deleteEmptyFoldersRecursivelyUpAndDown($subPath); 
     } 
    } 
    } 
} 

給出的路徑是一個目錄,我們檢查,如果使用我們的遞歸函數是。 如果是,我們刪除它並遞歸檢查父目錄。 如果不是,我們遍歷其內容以找到空文件夾,再次遞歸地調用函數本身。

有了這兩個功能,您就擁有了所有您需要的功能。只需遍歷路徑數組,並在所有條目上使用deleteEmptyFoldersRecursivelyUpAndDown。如果他們有問題,你會設法調試他們我假設。

+0

我將檢查遞歸空目錄的函數..可能爲empt3/empt2/empt3($ directoryContent)不會返回0 –

+0

可能scandir計數。並..這就是爲什麼$ directoryContent永遠不會變爲0.當我使用像count($ directoryContent)== 2這種情況下不識別像/ empty/empty2/empty3這樣的文件夾只能找到/ empty3 –

+0

@DenizPorsuk True。正如文檔在示例中所述,它確實返回'.'和'..'。我做了一個編輯。如果有效,你應該接受我的答案。 –