PHP:删除目录和内容 - 最安全,最可靠的方法

时间:2014-01-15 19:16:45

标签: php

在项目中,我可以创建目录和文件以及编辑这些文件。但现在我正在添加一个删除功能来删除目录和其中的所有内容。我做了一些研究,发现2009年的堆栈溢出答案有两种选择。我很好奇哪一个更好,如果有两个安全性的任何更新(只是确保我使用安全的方法)。下面是答案的复制和粘贴。

Stack Overflow Answer:

此功能允许您删除任何文件夹(只要它是可写的)及其文件和子目录。

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

或者没有使用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;
    } 

2 个答案:

答案 0 :(得分:2)

您还可以使用基础OS命令执行此操作:

if(is_dir($path)) {
    $path_escaped = escapeshellcmd(realpath($path));
    $output = shell_exec('rm -fR ' . $path_escaped);
}

应该注意的是,您肯定希望能够验证提供的`$ path值(如果来自不受信任的源)是否属于您希望允许此类功能的目录或目录集。

例如,您可以执行以下操作:

$allowable_delete_dirs = array(
    '/var/www/some_dir/',
    '/var/www/some_other_dir/'
);

if(is_dir($path)) {
    $real_path = realpath($path);
    $result_array = array_filter($allowable_delete_dirs, function($value) use ($real_path) {
        return (str_pos($real_path, $value) === 0 && $real_path !== $value);
    }
    if (count($result_array) > 0) {
        // the path provided matches one or more of the allowable directories
        $output = shell_exec('rm -fR ' . escapeshellcmd($real_path));
    }
}

答案 1 :(得分:0)

使用此方法删除任何目录或文件,即使目录包含子目录:

<?php

function list_files_dirs($dir) {
    if (!is_dir($dir))
        return ('Directory ' . $dir . ' doesn\'t exists.');
    $files = scandir($dir);
    unset($files[array_search('.', $files)]);
    unset($files[array_search('..', $files)]);
    return $files;
}

function delete_files($dir) {
    if (substr($dir, -1) == '/')
        $dir = substr($dir, 0, strlen($dir) - 1);
    if (!is_dir($dir) && !file_exists($dir))
        return $dir . ' doesn\'t exists.';

    function rmdir_recursive($dir, $instance) {
        foreach (list_files_dirs($dir) as $file) {
            if (is_dir("$dir/$file"))
                rmdir_recursive($dir . "/" . $file, $instance);
            else
                unlink($dir . "/" . $file);
        }
        rmdir($dir);
    }

    rmdir_recursive($dir, $this);
    return true;
}
echo delete_files("directory/or/file");
?>