Remove empty subfolders with PHP

后端 未结 6 1274
小鲜肉
小鲜肉 2020-12-09 22:38

I am working on a PHP function that will recursively remove all sub-folders that contain no files starting from a given absolute path.

Here is the code developed so

相关标签:
6条回答
  • 2020-12-09 22:44

    You can execute a unix command to remove empty directories.

    exec("find $starting_from_path -type d -empty -exec rmdir {} \; 2>/dev/null");

    0 讨论(0)
  • 2020-12-09 22:46

    You can try this.

    function removeEmptySubfolders($path){
    
      if(substr($path,-1)!= DIRECTORY_SEPARATOR){
        $path .= DIRECTORY_SEPARATOR;
      }
      $d2 = array('.','..');
      $dirs = array_diff(glob($path.'*', GLOB_ONLYDIR),$d2);
      foreach($dirs as $d){
        removeEmptySubfolders($d);
      }
    
      if(count(array_diff(glob($path.'*'),$d2))===0){
        $checkEmpSubDir = explode(DIRECTORY_SEPARATOR,$path);
        for($i=count($checkEmpSubDir)-1;$i>0;$i--){
          $path = substr(str_replace($checkEmpSubDir[$i],"",$path),0,-1);
    
          if(($files = @scandir($path)) && count($files) <= 2){
            rmdir($path);
          }
        }
      }
    }
    
    0 讨论(0)
  • 2020-12-09 22:54

    This line

    $ret = $ret ? $ret : $res;
    

    Could be made a little more readable:

    $ret = $ret || $res;
    

    Or if PHP has the bitwise operator:

    $ret |= $res;
    
    0 讨论(0)
  • 2020-12-09 23:01

    This would spell trouble because calling RemoveEmptySubFolders a few times would probably spell errors because each time you call the function, the other 2 functions are defined again. If they have already been defined, PHP will throw an error saying a function of the same name has already been defined.

    Instead try it recursively:

    function removeEmptySubfolders($path){
    
      if(substr($path,-1)!= DIRECTORY_SEPARATOR){
        $path .= DIRECTORY_SEPARATOR;
      }
      $d2 = array('.','..');
      $dirs = array_diff(glob($path.'*', GLOB_ONLYDIR),$d2);
      foreach($dirs as $d){
         removeEmptySubfolders($d);
      }
    
      if(count(array_diff(glob($path.'*'),$d2))===0){
        rmdir($path);
      }
    
    }
    

    Tested, working nicely. Windows 7 PHP 5.3.0 XAMPP

    0 讨论(0)
  • 2020-12-09 23:02

    Solution for Linux, using command line tool but faster and simpler than with pure PHP

    /**
     * Remove all empty subdirectories
     * @param string $dirPath path to base directory
     * @param bool $deleteBaseDir - Delete also basedir if it is empty
     */
    public static function removeEmptyDirs($dirPath, $deleteBaseDir = false) {
    
        if (stristr($dirPath, "'")) {
            trigger_error('Disallowed character `Single quote` (\') in provided `$dirPath` parameter', E_USER_ERROR);
        }
    
        if (substr($dirPath, -1) != '/') {
            $dirPath .= '/';
        }
    
        $modif = $deleteBaseDir ? '' : '*';
        exec("find '".$dirPath."'".$modif." -empty -type d -delete", $out);
    }
    

    If you need Windows support, use PHP_OS constant and this one-liner

    for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"`enter code here
    
    0 讨论(0)
  • 2020-12-09 23:10

    If you have empty folder within empty folder within empty folder, you'll need to loop through ALL folders three times. All this, because you go breadth first - test folder BEFORE testing its children. Instead, you should go into child folders before testing if parent is empty, this way one pass will be sufficient.

    function RemoveEmptySubFolders($path)
    {
      $empty=true;
      foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file)
      {
         if (is_dir($file))
         {
            if (!RemoveEmptySubFolders($file)) $empty=false;
         }
         else
         {
            $empty=false;
         }
      }
      if ($empty) rmdir($path);
      return $empty;
    }
    

    By the way, glob does not return . and .. entries.

    Shorter version:

    function RemoveEmptySubFolders($path)
    {
      $empty=true;
      foreach (glob($path.DIRECTORY_SEPARATOR."*") as $file)
      {
         $empty &= is_dir($file) && RemoveEmptySubFolders($file);
      }
      return $empty && rmdir($path);
    }
    
    0 讨论(0)
提交回复
热议问题