23

I need a script which can remove a whole directory with all their subfolders, files and etc. I tried with this function which I found in internet before few months ago but it not work completely.

function deleteFile($dir) {
    if(substr($dir, strlen($dir)-1, 1) != '/') { 
        $dir .= '/'; 
    }
    if($handle = opendir($dir)) { 
        while($obj = readdir($handle)) { 
            if($obj != '.' && $obj != '..') { 
                if(is_dir($dir.$obj)) { 
                    if(!deleteFile($dir.$obj)) {
                        echo $dir.$obj."<br />";
                        return false;
                    }
                }
                elseif(is_file($dir.$obj)) { 
                    if(!unlink($dir.$obj)) {
                        echo $dir.$obj."<br />";
                        return false;
                    }
                }
            }
        }
        closedir($handle); 
        if(!@rmdir($dir)) {
            echo $dir.'<br />';
            return false;
        }
        return true;
    }
    return true;
}

For the test I use a unpacked archive of prestashop and I try to delete the folder where archive is unpacked but it doesn't work.

/home/***/public_html/prestashop/img/p/3/
/home/***/public_html/prestashop/img/p/3
/home/***/public_html/prestashop/img/p
/home/***/public_html/prestashop/img

These are the problem folders. At the first time I think - "May is a problem with the chmod of the files" but when I test with all files chmod permission 755 (after that with 777) - the result was the same.

tshepang
  • 12,111
  • 21
  • 91
  • 136

5 Answers5

82
<?php
  function rrmdir($dir) {
  if (is_dir($dir)) {
    $objects = scandir($dir);
    foreach ($objects as $object) {
      if ($object != "." && $object != "..") {
        if (filetype($dir."/".$object) == "dir") 
           rrmdir($dir."/".$object); 
        else unlink   ($dir."/".$object);
      }
    }
    reset($objects);
    rmdir($dir);
  }
 }
?>

Try out the above code from a comment on php.net

Worked fine for me

gilad905
  • 2,842
  • 2
  • 16
  • 23
donald123
  • 5,638
  • 3
  • 26
  • 23
  • This is really nice example. It does deletes files and subfolders. – Amir Md Amiruzzaman Dec 15 '14 at 20:21
  • 5
    Good answer Donald. I know it's obvious to most, but I think it needs saying: BE REALLY CAREFUL when using this function (or any other on this page). It can (and will) wipe out your entire site if you give it the wrong parameter. – Jamie G Apr 07 '15 at 14:06
  • Is there a way to detect that it successfully delete the folder? Like it returns true? – MeetMahPuppy Apr 16 '16 at 05:13
  • take a look at http://php.net/manual/en/function.rmdir.php **rmdir()** return bool ... so you can use it – donald123 Apr 18 '16 at 09:45
  • Why do i get: Fatal error: Uncaught Error: Call to undefined function rrmdir() ? – Björn C Sep 10 '20 at 07:49
10
function delete_files($dir) { 
  foreach(glob($dir . '/*') as $file) { 
    if(is_dir($file)) delete_files($file); else unlink($file); 
  } rmdir($dir); 
}
GIPSSTAR
  • 2,050
  • 1
  • 25
  • 20
  • 3
    Add some text, you should at least say something, not just dump code. Even a "This should do the trick:" is fine. – sashoalm Jan 21 '15 at 10:34
  • If the initial folder is wrong, glob() returns false and you get an error. It's better to test 'if is_dir($dir)' as first instruction, maybe return true on success, false otherwise. Anyway it considers each entry. If it's a directory it's deleted with the recursive call 'delete_file' otherwise it's a file and it's deleted with unlink(). At the end the $dir is empty so it can be removed with 'rmdir'. – Fil Jul 04 '20 at 17:36
7

You can use a cleaner method for doing a recursive delete of a directory.

Example:

function recursiveRemove($dir) {
    $structure = glob(rtrim($dir, "/").'/*');
    if (is_array($structure)) {
        foreach($structure as $file) {
            if (is_dir($file)) recursiveRemove($file);
            elseif (is_file($file)) unlink($file);
        }
    }
    rmdir($dir);
}

Usage:

recursiveRemove("test/dir/");
Addramyr
  • 254
  • 4
  • 11
3

The easiest and the best way using the system() method

$dir = dirname ( "/log" );
if ($handle = opendir($dir)) {
    while (( $file = readdir($handle)) !== false ) {
        if ($file != "." && $file != "..") {
            system("rm -rf ".escapeshellarg($dir.'/'.$file));
        }
    }
}
closedir($handle);
Ale_
  • 85
  • 7
  • 1
    If you have no access to the shell (as for many hosting services) I think you cannot use 'system' method. – Fil Jul 04 '20 at 17:29
1
/**
 * Deletes a directory and all files and folders under it
 * @return Null
 * @param $dir String Directory Path
 */
function rmdir_files($dir) {
 $dh = opendir($dir);
 if ($dh) {
  while($file = readdir($dh)) {
   if (!in_array($file, array('.', '..'))) {
    if (is_file($dir.$file)) {
     unlink($dir.$file);
    }
    else if (is_dir($dir.$file)) {
     rmdir_files($dir.$file);
    }
   }
  }
  rmdir($dir);
 }
}
jit
  • 1,616
  • 3
  • 21
  • 49