How to delete a folder with contents using PHP

72,116

Solution 1

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

Solution 2

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!!!

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

Solution 4

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.

Solution 5

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

Share:
72,116
Fero
Author by

Fero

C00L Developer....

Updated on October 06, 2020

Comments

  • Fero
    Fero over 3 years

    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.

  • Alix Axel
    Alix Axel over 14 years
    @Randell: GLOB_MARK - Adds a slash to each directory returned.
  • Fero
    Fero over 14 years
    i hope rmdir will delete only the folder which has no contents. if it has contents it will not delete the folder.
  • ryeguy
    ryeguy over 14 years
    Probably someone here trying to raise their answer to the top. +1 to offset.
  • Volomike
    Volomike about 12 years
    Not recommended at all for production.
  • ryeguy
    ryeguy about 12 years
    @Volomike: Why? This is almost certainly faster than a php solution.
  • Volomike
    Volomike almost 12 years
    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.
  • skrilled
    skrilled over 9 years
    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.
  • David L
    David L over 9 years
    Great method, man. I was using the very simpler command: <?php system("rm -r RESOURCE_PATH"); ?>, 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.
  • yoano
    yoano about 8 years
    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?
  • mghhgm
    mghhgm almost 7 years
    Like, best answer 👍