2014-01-15 43 views
0

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

Stack Overflow Answer:

该功能将允许你删除任何文件夹(只要它是可写的),它的文件和子目录。使用RecursiveDirectoryIterator

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

或者不递归:

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

我没有看到你由* secure *表示。如果你不知道自己在做什么,两者都会造成损害。 –

+0

像代码中的漏洞或已知的不安全方法一样安全。我知道有些东西因为已知的漏洞而不被推荐,只是想确保它们不包含任何漏洞。 – kdjernigan

+0

^所以你问的是代码审查?如果是的话,那么这可能是OT – reikyoushin

回答

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)); 
    } 
} 
+2

那么如果'$ path'碰巧是'/'会发生什么? –

+0

@crypticツ很可能,除非以超级用户身份运行,否则PHP将无法执行。尽管如此,人们可能想要限制可以用这种方式删除的目录范围,但是原始问题的例子中也没有涉及到。对我来说,这可以通过确保将要使用的路径落在已知的目录结构内来实现。我会为答案添加评论。 –

+0

我该如何确保路径属于某个目录结构? – kdjernigan

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"); 
?> 
+0

这难以修改以限制功能到特定的目录吗?例如,它只能删除'$ _SERVER ['DOCUMENT_ROOT']。'/ directory /''文件夹中的文件/文件夹。 – kdjernigan

+1

只需在开始时加一个'if'并检查是否不允许目录,然后'die('not allowed')' –

相关问题