php 删除包含文件的目录?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3349753/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 09:25:52  来源:igfitidea点击:

Delete directory with files in it?

phprmdir

提问by matt

I wonder, what's the easiest way to delete a directory with all its files in it?

我想知道,删除包含所有文件的目录的最简单方法是什么?

I'm using rmdir(PATH . '/' . $value);to delete a folder, however, if there are files inside of it, I simply can't delete it.

rmdir(PATH . '/' . $value);用来删除一个文件夹,但是,如果里面有文件,我根本无法删除它。

回答by alcuadrado

There are at least two options available nowadays.

现在至少有两种选择。

  1. Before deleting the folder, delete all its files and folders (and this means recursion!). Here is an example:

    public static function deleteDir($dirPath) {
        if (! is_dir($dirPath)) {
            throw new InvalidArgumentException("$dirPath must be a directory");
        }
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }
        $files = glob($dirPath . '*', GLOB_MARK);
        foreach ($files as $file) {
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                unlink($file);
            }
        }
        rmdir($dirPath);
    }
    
  2. And if you are using 5.2+ you can use a RecursiveIterator to do it without implementing the recursion yourself:

    $dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
    $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
    $files = new RecursiveIteratorIterator($it,
                 RecursiveIteratorIterator::CHILD_FIRST);
    foreach($files as $file) {
        if ($file->isDir()){
            rmdir($file->getRealPath());
        } else {
            unlink($file->getRealPath());
        }
    }
    rmdir($dir);
    
  1. 在删除文件夹之前,删除其所有文件和文件夹(这意味着递归!)。下面是一个例子:

    public static function deleteDir($dirPath) {
        if (! is_dir($dirPath)) {
            throw new InvalidArgumentException("$dirPath must be a directory");
        }
        if (substr($dirPath, strlen($dirPath) - 1, 1) != '/') {
            $dirPath .= '/';
        }
        $files = glob($dirPath . '*', GLOB_MARK);
        foreach ($files as $file) {
            if (is_dir($file)) {
                self::deleteDir($file);
            } else {
                unlink($file);
            }
        }
        rmdir($dirPath);
    }
    
  2. 如果您使用的是 5.2+,您可以使用 RecursiveIterator 来完成它,而无需自己实现递归:

    $dir = 'samples' . DIRECTORY_SEPARATOR . 'sampledirtree';
    $it = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
    $files = new RecursiveIteratorIterator($it,
                 RecursiveIteratorIterator::CHILD_FIRST);
    foreach($files as $file) {
        if ($file->isDir()){
            rmdir($file->getRealPath());
        } else {
            unlink($file->getRealPath());
        }
    }
    rmdir($dir);
    

回答by user3033886

I generally use this to delete all files in a folder:

我通常使用它来删除文件夹中的所有文件:

array_map('unlink', glob("$dirname/*.*"));

And then you can do

然后你可以做

rmdir($dirname);

回答by Your Common Sense

what's the easiest way to delete a directory with all it's files in it?

删除包含所有文件的目录的最简单方法是什么?

system("rm -rf ".escapeshellarg($dir));

回答by Blaise

Short function that does the job:

完成这项工作的简短功能:

function deleteDir($path) {
    return is_file($path) ?
            @unlink($path) :
            array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}

I use it in a Utils class like this:

我在 Utils 类中使用它,如下所示:

class Utils {
    public static function deleteDir($path) {
        $class_func = array(__CLASS__, __FUNCTION__);
        return is_file($path) ?
                @unlink($path) :
                array_map($class_func, glob($path.'/*')) == @rmdir($path);
    }
}


With great power comes great responsibility: When you call this function with an empty value, it will delete files starting in root (/). As a safeguard you can check if path is empty:

能力越大责任越大:当您使用空值调用此函数时,它将删除以 root ( /)开头的文件。作为保护措施,您可以检查路径是否为空:

function deleteDir($path) {
    if (empty($path)) { 
        return false;
    }
    return is_file($path) ?
            @unlink($path) :
            array_map(__FUNCTION__, glob($path.'/*')) == @rmdir($path);
}

回答by German Latorre

As seen in most voted comment on PHP manual page about rmdir()(see http://php.net/manual/es/function.rmdir.php), glob()function does not return hidden files. scandir()is provided as an alternative that solves that issue.

正如 PHP 手册页上投票最多的评论所见rmdir()(参见http://php.net/manual/es/function.rmdir.php),glob()函数不返回隐藏文件。 scandir()提供作为解决该问题的替代方案。

Algorithm described there (which worked like a charm in my case) is:

那里描述的算法(在我的情况下就像一个魅力)是:

<?php 
    function delTree($dir)
    { 
        $files = array_diff(scandir($dir), array('.', '..')); 

        foreach ($files as $file) { 
            (is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file"); 
        }

        return rmdir($dir); 
    } 
?>

回答by Playnox

This is a shorter Version works great to me

这是一个较短的版本对我来说很好用

function deleteDirectory($dirPath) {
    if (is_dir($dirPath)) {
        $objects = scandir($dirPath);
        foreach ($objects as $object) {
            if ($object != "." && $object !="..") {
                if (filetype($dirPath . DIRECTORY_SEPARATOR . $object) == "dir") {
                    deleteDirectory($dirPath . DIRECTORY_SEPARATOR . $object);
                } else {
                    unlink($dirPath . DIRECTORY_SEPARATOR . $object);
                }
            }
        }
    reset($objects);
    rmdir($dirPath);
    }
}

回答by Gras Double

You may use Symfony's Filesystem(code):

您可以使用 Symfony 的文件系统代码):

// composer require symfony/filesystem

use Symfony\Component\Filesystem\Filesystem;

(new Filesystem)->remove($dir);

However I couldn't delete some complex directory structures with this method, so first you should try it to ensure it's working properly.

但是我不能用这种方法删除一些复杂的目录结构,所以首先你应该尝试它以确保它正常工作。


I could delete the said directory structure using a Windows specific implementation:


我可以使用 Windows 特定的实现删除上述目录结构:

$dir = strtr($dir, '/', '\');
// quotes are important, otherwise one could
// delete "foo" instead of "foo bar"
system('RMDIR /S /Q "'.$dir.'"');


And just for the sake of completeness, here is an old code of mine:


为了完整起见,这是我的旧代码:

function xrmdir($dir) {
    $items = scandir($dir);
    foreach ($items as $item) {
        if ($item === '.' || $item === '..') {
            continue;
        }
        $path = $dir.'/'.$item;
        if (is_dir($path)) {
            xrmdir($path);
        } else {
            unlink($path);
        }
    }
    rmdir($dir);
}

回答by Tommz

Here you have one nice and simple recursion for deleting all files in source directory including that directory:

在这里,您有一个很好且简单的递归来删除源目录中的所有文件,包括该目录:

function delete_dir($src) { 
    $dir = opendir($src);
    while(false !== ( $file = readdir($dir)) ) { 
        if (( $file != '.' ) && ( $file != '..' )) { 
            if ( is_dir($src . '/' . $file) ) { 
                delete_dir($src . '/' . $file); 
            } 
            else { 
                unlink($src . '/' . $file); 
            } 
        } 
    } 
    closedir($dir); 
    rmdir($src);

}

Function is based on recursion made for copying directory. You can find that function here: Copy entire contents of a directory to another using php

函数基于为复制目录而进行的递归。您可以在此处找到该功能: 使用 php 将目录的全部内容复制到另一个目录

回答by adrian

What about this:

那这个呢:

function recursiveDelete($dirPath, $deleteParent = true){
    foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dirPath, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST) as $path) {
        $path->isFile() ? unlink($path->getPathname()) : rmdir($path->getPathname());
    }
    if($deleteParent) rmdir($dirPath);
}

回答by T.Todua

The Best Solution for me

对我来说最好的解决方案

my_folder_delete("../path/folder");

code:

代码:

function my_folder_delete($path) {
    if(!empty($path) && is_dir($path) ){
        $dir  = new RecursiveDirectoryIterator($path, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs are not included,otherwise DISASTER HAPPENS :)
        $files = new RecursiveIteratorIterator($dir, RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $f) {if (is_file($f)) {unlink($f);} else {$empty_dirs[] = $f;} } if (!empty($empty_dirs)) {foreach ($empty_dirs as $eachDir) {rmdir($eachDir);}} rmdir($path);
    }
}

p.s. REMEMBER!
dont pass EMPTY VALUES to any Directory deleting functions!!! (backup them always, otherwise one day you might get DISASTER!!)

ps记住!
不要将 EMPTY VALUES 传递给任何目录删除功能!!!(总是备份它们,否则有一天你可能会遇到灾难!!)