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
  • 9,687
  • 6
  • 54
  • 105
Fero
  • 12,491
  • 45
  • 111
  • 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

88

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
  • 147,060
  • 89
  • 388
  • 491
  • 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 – mghhgm Jun 16 '17 at 19: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
  • 224,347
  • 65
  • 373
  • 385
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ń
  • 25,163
  • 16
  • 85
  • 109
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,018
  • 5
  • 43
  • 70
2

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

ryeguy
  • 63,287
  • 56
  • 190
  • 257
  • 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
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
  • 61,521
  • 14
  • 148
  • 143
  • 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