2014-05-05 116 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。正如文档在示例中所述,它确实返回'.'和'..'。我做了一个编辑。如果有效,你应该接受我的答案。 –