30

I need to delete a folder with contents using PHP. rmdir() and unlink() delete empty folders, but are not able to delete folders which have contents.

TRiG
  • 10,148
  • 7
  • 57
  • 107
Fero
  • 12,969
  • 46
  • 116
  • 157
  • 6
    @@Maerlyn: I've posted this question on Aug 26 2009. The duplicate one which you mentioned was posted on July 28 2010.. I believe you know what to do NOW... Before doing something please cross check once. – Fero Jan 21 '15 at 08:53

6 Answers6

92

This function will allow you to delete any folder (as long as it's writable) and it's files and subdirectories.

function Delete($path)
{
    if (is_dir($path) === true)
    {
        $files = array_diff(scandir($path), array('.', '..'));

        foreach ($files as $file)
        {
            Delete(realpath($path) . '/' . $file);
        }

        return rmdir($path);
    }

    else if (is_file($path) === true)
    {
        return unlink($path);
    }

    return false;
}

Or without recursion using RecursiveDirectoryIterator:

function Delete($path)
{
    if (is_dir($path) === true)
    {
        $files = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::CHILD_FIRST);

        foreach ($files as $file)
        {
            if (in_array($file->getBasename(), array('.', '..')) !== true)
            {
                if ($file->isDir() === true)
                {
                    rmdir($file->getPathName());
                }

                else if (($file->isFile() === true) || ($file->isLink() === true))
                {
                    unlink($file->getPathname());
                }
            }
        }

        return rmdir($path);
    }

    else if ((is_file($path) === true) || (is_link($path) === true))
    {
        return unlink($path);
    }

    return false;
}
Alix Axel
  • 151,645
  • 95
  • 393
  • 500
  • 2
    Great method, man. I was using the very simpler command: , but unfortunately some servers don't allow the system command, so yours (I chose the first one)is a very good and simple substitution. Thanks, brother. – David L Oct 20 '14 at 20:51
  • 2
    Does this also works for relative paths? So let's say the full path is "/var/www/html/folder_and_files_to_delete/" And the delete script is placed in "/var/www/html/delete_folders_and_files.php". Can I just take "folder_and_files_to_delete" as path? – yoano Mar 31 '16 at 17:59
  • Like, best answer – Milad Ghiravani Jun 16 '17 at 19:33
  • In 2022 the first code example gives `Call to undefined function Delete()` inside the `foreach ($files as $file)` changing `Delete(realpath($path) . '/' . $file);` into `unlink(realpath($path) . '/' . $file);` solved it for me. – purple11111 Dec 02 '22 at 04:33
3

You need to loop around the folder contents (including the contents of any subfolders) and remove them first.

There's an example here: http://lixlpixel.org/recursive_function/php/recursive_directory_delete/

Be careful with it!!!

Fenton
  • 241,084
  • 71
  • 387
  • 401
3

You could always cheat and do shell_exec("rm -rf /path/to/folder");

ryeguy
  • 65,519
  • 58
  • 198
  • 260
  • Not recommended at all for production. – Volomike Apr 20 '12 at 06:53
  • 2
    @Volomike: Why? This is almost certainly faster than a php solution. – ryeguy Apr 27 '12 at 02:49
  • 5
    There's better handling in PHP -- it will detect if something goes wrong in the process. Plus, most shared hosting providers block shell commands from PHP. Third, it's not portable to Windows. And I definitely wouldn't write software for sale with something like this in it. – Volomike Apr 28 '12 at 14:26
  • That's an arguable point from Volomike. If you are on a linux environment and in control of your own destiny, this command is the best option here and I would definitely choose this over options which make a user wait several seconds. – skrilled Oct 07 '14 at 18:19
3

There is no single function build into PHP that would allow this, you have to write your own with rmdir and unlink.

An example (taken from a comment on php.net docs):

<?
// ensure $dir ends with a slash
function delTree($dir) {
    $files = glob( $dir . '*', GLOB_MARK );
    foreach( $files as $file ){
        if( substr( $file, -1 ) == '/' )
            delTree( $file );
        else
            unlink( $file );
    }
    rmdir( $dir );
}
?>
Krzysztof Krasoń
  • 26,515
  • 16
  • 89
  • 115
3

Here's a script that will do just what you need:

/**
 * Recursively delete a directory
 *
 * @param string $dir Directory name
 * @param boolean $deleteRootToo Delete specified top-level directory as well
 */
function unlinkRecursive($dir, $deleteRootToo)
{
    if(!$dh = @opendir($dir))
    {
        return;
    }
    while (false !== ($obj = readdir($dh)))
    {
        if($obj == '.' || $obj == '..')
        {
            continue;
        }

        if (!@unlink($dir . '/' . $obj))
        {
            unlinkRecursive($dir.'/'.$obj, true);
        }
    }

    closedir($dh);

    if ($deleteRootToo)
    {
        @rmdir($dir);
    }

    return;
}

I got it from php.net and it works.

Randell
  • 6,112
  • 6
  • 45
  • 70
1

You will have to delete all the files recursively. There are plenty example functions in the comments of the rmdir manual page:

http://www.php.net/rmdir

Ferdinand Beyer
  • 64,979
  • 15
  • 154
  • 145
  • i hope rmdir will delete only the folder which has no contents. if it has contents it will not delete the folder. – Fero Aug 26 '09 at 13:36