Hướng dẫn php remove directory recursively

I am using PHP to move the contents of a images subfolder

GalleryName/images/

into another folder. After the move, I need to delete the GalleryName directory and everything else inside it.

I know that rmdir[] won't work unless the directory is empty. I've spent a while trying to build a recursive function to scandir[] starting from the top and then unlink[] if it's a file and scandir[] if it's a directory, then rmdir[] each empty directory as I go.

So far it's not working exactly right, and I began to think -- isn't this a ridiculously simple function that PHP should be able to do? Removing a directory?

So is there something I'm missing? Or is there at least a proven function that people use for this action?

Any help would be appreciated.

PS I trust you all here more than the comments on the php.net site -- there are hundreds of functions there but I am interested to hear if any of you here recommend one over others.

cweiske

29k13 gold badges127 silver badges189 bronze badges

asked Sep 10, 2009 at 19:47

2

What about this?

function rmdir_recursive[$dirPath]{
    if[!empty[$dirPath] && is_dir[$dirPath] ]{
        $dirObj= new RecursiveDirectoryIterator[$dirPath, RecursiveDirectoryIterator::SKIP_DOTS]; //upper dirs not included,otherwise DISASTER HAPPENS :]
        $files = new RecursiveIteratorIterator[$dirObj, RecursiveIteratorIterator::CHILD_FIRST];
        foreach [$files as $path] 
            $path->isDir[] && !$path->isLink[] ? rmdir[$path->getPathname[]] : unlink[$path->getPathname[]];
        rmdir[$dirPath];
        return true;
    }
    return false;
}

T.Todua

50k19 gold badges216 silver badges213 bronze badges

answered Feb 27, 2013 at 12:04

barbushinbarbushin

5,1135 gold badges35 silver badges43 bronze badges

6

This is the recursive function I've created/modifed and that finally seems to be working. Hopefully there isn't anything too dangerous in it.

function destroy_dir[$dir] { 
    if [!is_dir[$dir] || is_link[$dir]] return unlink[$dir]; 
    foreach [scandir[$dir] as $file] { 
        if [$file == '.' || $file == '..'] continue; 
        if [!destroy_dir[$dir . DIRECTORY_SEPARATOR . $file]] { 
            chmod[$dir . DIRECTORY_SEPARATOR . $file, 0777]; 
            if [!destroy_dir[$dir . DIRECTORY_SEPARATOR . $file]] return false; 
        }; 
    } 
    return rmdir[$dir]; 
} 

Nate Cook

91.3k32 gold badges214 silver badges176 bronze badges

answered Sep 10, 2009 at 20:03

rhodesjasonrhodesjason

4,8259 gold badges43 silver badges58 bronze badges

1

If the server of application runs linux, just use the shell_exec[] function, and provide it the rm -R command, like this:

    $realPath = realpath[$dir_path];

    if[$realPath === FALSE]{
         throw new \Exception['Directory does not exist'];
    }

    shell_exec["rm ". escapeshellarg[$realPath] ." -R"];

Explanation:

Removes the specified directory recursively only if the path exists and escapes the path so that it can only be used as a shell argument to avoid shell command injection.

If you wouldnt use escapeshellarg one could execute commands by naming the directory to be removed after a command.

answered Dec 29, 2013 at 13:03

ValentoniValentoni

3081 silver badge19 bronze badges

3

I've adapted a function which handles hidden unix files with the dot prefix and uses glob:

public static function deleteDir[$path] {
    if [!is_dir[$path]] {
        throw new InvalidArgumentException["$path is not a directory"];
    }
    if [substr[$path, strlen[$path] - 1, 1] != '/'] {
        $path .= '/';
    }
    $dotfiles = glob[$path . '.*', GLOB_MARK];
    $files = glob[$path . '*', GLOB_MARK];
    $files = array_merge[$files, $dotfiles];
    foreach [$files as $file] {
        if [basename[$file] == '.' || basename[$file] == '..'] {
            continue;
        } else if [is_dir[$file]] {
            self::deleteDir[$file];
        } else {
            unlink[$file];
        }
    }
    rmdir[$path];
}

answered Dec 26, 2012 at 2:48

Aram KocharyanAram Kocharyan

20k11 gold badges78 silver badges96 bronze badges

I prefer an enhaced method derived from the php help pages //php.net/manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if [!empty[$path] && ...]
 {
  if [PHP_OS === 'Windows']
  {
    exec['rd /s /q "'.$path.'"'];
  }
  else
  {
      exec['rm -rf "'.$path.'"'];
  }
}
else
{
    error_log['path not valid:$path'.var_export[$path, true]];
}

reasons for my decision:

  • less code
  • speed
  • keep it simple

answered Apr 22, 2015 at 15:15

public static function rrmdir[$dir]
{
    if [is_dir[$dir]] {
        $files = scandir[$dir];
        foreach [$files as $file] {
            if [$file != "." && $file != ".."] {
                if [filetype[$dir . "/" . $file] == "dir"]
                    self::rrmdir[$dir . "/" . $file];
                else
                    unlink[$dir . "/" . $file];
            }
        }
        reset[$files];
        rmdir[$dir];
    }
}

answered Apr 24, 2018 at 8:13

yousefyousef

1,09210 silver badges13 bronze badges

Chủ Đề