递归查找空文件夹并递归删除它们 [英] Finding empty folders recursively and delete them recursively

查看:47
本文介绍了递归查找空文件夹并递归删除它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个已传递给数组的目录树.

I have an directory tree which has been passed to array.

我想在这个数组中有空文件夹.

I would like to there empty folders inside this array.

如何确定像 /wp-content/uploads/2014/02//wp-content/uploads/2014/ 这样的空文件夹.如何递归删除它们.

How can I determine empty folders like /wp-content/uploads/2014/02/ and /wp-content/uploads/2014/. How can I delete them recursively.

这是我的数组

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 的付出.谁想以性能递归删除空文件夹,可以使用此解决方案.

Thank you very much to Andresch Serj for him effords. Who wants to delete empty folders recursively with performance, you can use this solution.

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);

推荐答案

使用 foreach.

foreach ($filesArray as $file) {

然后对于每个文件,使用 <检查它是否是一个文件夹code>is_dir 像这样

Then for each file, check if it is a folder using is_dir like this

if (is_dir ($file)) {

如果是文件夹/目录,读取目录,例如使用scandir.

If it is a folder/directory, read the directory, for instanse using scandir.

$directoryContent = scandir($file);

如果scandir的结果是空的,你有一个空文件夹,你可以用取消链接.

If the result of scandir is empty, you have an empty folder that you can delete with unlink.

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

如果您在使用 unlink 时遇到问题,您可能需要相应地设置文件权限.

If you have trouble with unlink, you may have to set file permissions accordingly.

如果你需要一个函数来递归删除给定一些 paht 的空子文件夹,你应该考虑阅读 SO 问题是评论中的链接.

If instead you need a function that recursively deletes empty subfolders given some paht, you should consider reading the SO question that was linkes in the comments.

编辑

考虑到您的评论后,您想要的是一个删除父文件夹的功能.所以对于一个geiven level1/level2/level3,其中level3 是空的,并且level2 中唯一的文件夹/文件你想要level2也将被删除.

After taking into consideration your comments, what you do want is a function that deletes parent folders as well. So for a geiven level1/level2/level3 where level3 is empty and the only folder/file in level2 you want level2 to be deleted as well.

因此,从您的示例数组中,您希望删除 ./wp-content/uploads/2014/ 而不仅仅是 ./wp-content/uploads/2014/10,但前提是 ./wp-content/uploads/2014/10 没有内容或子文件夹有内容.

So from your example array, you want ./wp-content/uploads/2014/ deleted and not just ./wp-content/uploads/2014/10, but only if ./wp-content/uploads/2014/10 has no content or subfolders with content.

那怎么做呢?

Simple:扩展您对该文件夹为空的天气检查.如果为空,则操作给定的文件/路径字符串以获取父文件夹.到现在为止,您确实应该将其外包给递归函数.

Simle: Extend your check for weather that folder is empty. If it is empty, manipoulate the given file/path string to get the parent folder. By now you should outsource this to a recursive functions indeed.

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;
}

所以这个函数递归地检查路径是否只有空文件夹或包含空文件夹的文件夹 - 递归地.现在您想检查您的路径并可能删除它们,向下和向上递归.

So this function checks recursively if a path has only empty folders or folders containing empty folders - recursively. Now you want to check your paths and maybe delete them, recursively downwards and upwards.

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);
      }
    }
  }
}

如果给定的路径是一个目录,我们会使用递归函数检查它是否为.如果是,我们将其删除并递归检查父目录.如果不是,我们遍历它的内容以找到空文件夹,再次递归调用函数本身.

If the given path is a directory, we check if it is empty using our recursive function. If it is, we delete it and recursively check the parent directory. If it is not, we iterate over its content to find empty folders, again calling the function itself recursively.

有了这两个功能,你就拥有了你需要的一切.只需遍历您的路径数组并在所有条目上使用 deleteEmptyFoldersRecursivelyUpAndDown.如果它们有问题,我想你会设法调试它们.

With these two function you have all you need. Simply iterate over your path array and use deleteEmptyFoldersRecursivelyUpAndDownon all entries. If they are faulty, you'll manage to debug them i presume.

这篇关于递归查找空文件夹并递归删除它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆