PHP ile boş klasörleri kaldırmak

6 Cevap php

Ben özyinelemeli verilen mutlak yolundan başlayarak hiçbir dosyaları içeren tüm alt klasörleri kaldırmak olacak bir PHP fonksiyonu üzerinde çalışıyorum.

İşte bugüne kadar geliştirilen kodu:

function RemoveEmptySubFolders($starting_from_path) {

    // Returns true if the folder contains no files
    function IsEmptyFolder($folder) {
        return (count(array_diff(glob($folder.DIRECTORY_SEPARATOR."*"), Array(".", ".."))) == 0);
    }

    // Cycles thorugh the subfolders of $from_path and
    // returns true if at least one empty folder has been removed
    function DoRemoveEmptyFolders($from_path) {
        if(IsEmptyFolder($from_path)) {
            rmdir($from_path);
            return true;
        }
        else {
            $Dirs = glob($from_path.DIRECTORY_SEPARATOR."*", GLOB_ONLYDIR);
            $ret = false;
            foreach($Dirs as $path) {
                $res = DoRemoveEmptyFolders($path);
                $ret = $ret ? $ret : $res;
            }
            return $ret;
        }
    }

    while (DoRemoveEmptyFolders($starting_from_path)) {}
}

Ben daha iyi performans kodu için herhangi bir fikir görmek çok mutlu olurdu ama benim testlerde başı olarak bu fonksiyon çalışır.

6 Cevap

Eğer boş klasörün içindeki boş klasörün içinde boş bir klasör varsa, TÜM klasörler döngü üç kez gerekir. Bütün bu, ilk genişliği gidin çünkü - sınama klasörü çocuklarını test ÖNCE. Bunun yerine, ebeveyn boş ise, bu şekilde bir geçiş yeterli olacaktır test etmeden önce alt klasörlere gitmek gerekir.

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

Bu arada, glob dönmez. ve .. girişleri.

Kısa bir versiyonu:

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

Sen boş dizinleri kaldırmak için bir Unix komutunu çalıştırabilirsiniz.

exec ("; 2> / dev / null $ starting_from_path-type d-boş-exec rmdir {} \ bulmak");

Bu hat

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

Biraz daha okunabilir yapılabilir:

$ret = $ret || $res;

Veya PHP bit operatörü varsa:

$ret |= $res;

Eğer işlevini çağırın her zaman, diğer 2 fonksiyonlar tekrar tanımlanır, çünkü çağıran RemoveEmptySubFolders birkaç kez muhtemelen hataları büyü çünkü bu sorun büyü olur. Onlar zaten tanımlanmış varsa, PHP aynı isimde bir fonksiyon zaten tanımlanmış olan söyleyerek bir hata atmak olacaktır.

Bunun yerine ardışık deneyin:

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

}

Güzel çalışma, test. Windows 7 PHP XAMPP 5.3.0

Bu deneyebilirsiniz.

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

Linux için çözüm, komut satırı aracını kullanarak ancak daha hızlı ve daha basit saf PHP ile daha

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

Windows desteğe ihtiyacınız varsa, PHP_OS sabit ve bu one-liner kullanın

for /f "delims=" %d in ('dir /s /b /ad ^| sort /r') do rd "%d"`enter code here