PHP 的递归删除目录函数?

发布于 2024-08-04 14:23:13 字数 553 浏览 2 评论 0原文

我正在使用 PHP 移动图像子文件夹的内容

图库名称/图像/

到另一个文件夹。移动后,我需要删除 GalleryName 目录以及其中的所有其他内容。

我知道除非目录为空,否则 rmdir() 将无法工作。我花了一段时间尝试从顶部开始构建 scandir() 的递归函数,然后构建 unlink() 如果它是文件和 scandir() 如果它是一个目录,则 rmdir() 每个空目录。

到目前为止,它还不能完全正常工作,我开始思考 -- 这不是 PHP 应该能够实现的一个极其简单的功能吗? 删除目录?

那么我缺少什么吗?或者至少有一个经过验证的函数可供人们用于此操作?

任何帮助将不胜感激。

PS 比起 php.net 网站上的评论,我更信任你们所有人 - 那里有数百个功能,但我很想听听你们中是否有人推荐其中一个。

I am using PHP to move the contents of a images subfolder

GalleryName/images/

into another folder. After the move, I need to delete the GalleryName directory and everything else inside it.

I know that rmdir() won't work unless the directory is empty. I've spent a while trying to build a recursive function to scandir() starting from the top and then unlink() if it's a file and scandir() if it's a directory, then rmdir() each empty directory as I go.

So far it's not working exactly right, and I began to think -- isn't this a ridiculously simple function that PHP should be able to do? Removing a directory?

So is there something I'm missing? Or is there at least a proven function that people use for this action?

Any help would be appreciated.

PS I trust you all here more than the comments on the php.net site -- there are hundreds of functions there but I am interested to hear if any of you here recommend one over others.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

海未深 2024-08-11 14:23:13

这又如何呢?

function rmdir_recursive($dirPath){
    if(!empty($dirPath) && is_dir($dirPath) ){
        $dirObj= new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs not included,otherwise DISASTER HAPPENS :)
        $files = new RecursiveIteratorIterator($dirObj, RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $path) 
            $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
        rmdir($dirPath);
        return true;
    }
    return false;
}

What about this?

function rmdir_recursive($dirPath){
    if(!empty($dirPath) && is_dir($dirPath) ){
        $dirObj= new RecursiveDirectoryIterator($dirPath, RecursiveDirectoryIterator::SKIP_DOTS); //upper dirs not included,otherwise DISASTER HAPPENS :)
        $files = new RecursiveIteratorIterator($dirObj, RecursiveIteratorIterator::CHILD_FIRST);
        foreach ($files as $path) 
            $path->isDir() && !$path->isLink() ? rmdir($path->getPathname()) : unlink($path->getPathname());
        rmdir($dirPath);
        return true;
    }
    return false;
}
甜柠檬 2024-08-11 14:23:13

这是我创建/修改的递归函数,它似乎终于起作用了。希望里面没有什么太危险的东西。

function destroy_dir($dir) { 
    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
    foreach (scandir($dir) as $file) { 
        if ($file == '.' || $file == '..') continue; 
        if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { 
            chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
            if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; 
        }; 
    } 
    return rmdir($dir); 
} 

This is the recursive function I've created/modifed and that finally seems to be working. Hopefully there isn't anything too dangerous in it.

function destroy_dir($dir) { 
    if (!is_dir($dir) || is_link($dir)) return unlink($dir); 
    foreach (scandir($dir) as $file) { 
        if ($file == '.' || $file == '..') continue; 
        if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) { 
            chmod($dir . DIRECTORY_SEPARATOR . $file, 0777); 
            if (!destroy_dir($dir . DIRECTORY_SEPARATOR . $file)) return false; 
        }; 
    } 
    return rmdir($dir); 
} 
白鸥掠海 2024-08-11 14:23:13

如果应用程序的服务器运行 linux,则只需使用 shell_exec() 函数,并为其提供 rm -R 命令,如下所示:

    $realPath = realpath($dir_path);

    if($realPath === FALSE){
         throw new \Exception('Directory does not exist');
    }

    shell_exec("rm ". escapeshellarg($realPath) ." -R");

说明:

仅当路径存在时才递归删除指定目录,并对路径进行转义,使其只能被访问用作 shell 参数以避免 shell 命令注入。

如果您不使用 escapeshellarg,则可以通过在命令后命名要删除的目录来执行命令。

If the server of application runs linux, just use the shell_exec() function, and provide it the rm -R command, like this:

    $realPath = realpath($dir_path);

    if($realPath === FALSE){
         throw new \Exception('Directory does not exist');
    }

    shell_exec("rm ". escapeshellarg($realPath) ." -R");

Explanation:

Removes the specified directory recursively only if the path exists and escapes the path so that it can only be used as a shell argument to avoid shell command injection.

If you wouldnt use escapeshellarg one could execute commands by naming the directory to be removed after a command.

反目相谮 2024-08-11 14:23:13

我改编了一个函数,它处理带有点前缀的隐藏 unix 文件并使用 glob:

public static function deleteDir($path) {
    if (!is_dir($path)) {
        throw new InvalidArgumentException("$path is not a directory");
    }
    if (substr($path, strlen($path) - 1, 1) != '/') {
        $path .= '/';
    }
    $dotfiles = glob($path . '.*', GLOB_MARK);
    $files = glob($path . '*', GLOB_MARK);
    $files = array_merge($files, $dotfiles);
    foreach ($files as $file) {
        if (basename($file) == '.' || basename($file) == '..') {
            continue;
        } else if (is_dir($file)) {
            self::deleteDir($file);
        } else {
            unlink($file);
        }
    }
    rmdir($path);
}

I've adapted a function which handles hidden unix files with the dot prefix and uses glob:

public static function deleteDir($path) {
    if (!is_dir($path)) {
        throw new InvalidArgumentException("$path is not a directory");
    }
    if (substr($path, strlen($path) - 1, 1) != '/') {
        $path .= '/';
    }
    $dotfiles = glob($path . '.*', GLOB_MARK);
    $files = glob($path . '*', GLOB_MARK);
    $files = array_merge($files, $dotfiles);
    foreach ($files as $file) {
        if (basename($file) == '.' || basename($file) == '..') {
            continue;
        } else if (is_dir($file)) {
            self::deleteDir($file);
        } else {
            unlink($file);
        }
    }
    rmdir($path);
}
是你 2024-08-11 14:23:13

我更喜欢从 php 帮助页面派生的增强方法 http://php.net/ Manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if (!empty($path) && ...)
 {
  if (PHP_OS === 'Windows')
  {
    exec('rd /s /q "'.$path.'"');
  }
  else
  {
      exec('rm -rf "'.$path.'"');
  }
}
else
{
    error_log('path not valid:$path'.var_export($path, true));
}

我决定的原因:

  • 代码
  • 速度
  • 较低,保持简单

I prefer an enhaced method derived from the php help pages http://php.net/manual/en/function.rmdir.php#115598

 // check accidential empty, root or relative pathes
 if (!empty($path) && ...)
 {
  if (PHP_OS === 'Windows')
  {
    exec('rd /s /q "'.$path.'"');
  }
  else
  {
      exec('rm -rf "'.$path.'"');
  }
}
else
{
    error_log('path not valid:$path'.var_export($path, true));
}

reasons for my decision:

  • less code
  • speed
  • keep it simple
萌面超妹 2024-08-11 14:23:13
public static function rrmdir($dir)
{
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file != "." && $file != "..") {
                if (filetype($dir . "/" . $file) == "dir")
                    self::rrmdir($dir . "/" . $file);
                else
                    unlink($dir . "/" . $file);
            }
        }
        reset($files);
        rmdir($dir);
    }
}
public static function rrmdir($dir)
{
    if (is_dir($dir)) {
        $files = scandir($dir);
        foreach ($files as $file) {
            if ($file != "." && $file != "..") {
                if (filetype($dir . "/" . $file) == "dir")
                    self::rrmdir($dir . "/" . $file);
                else
                    unlink($dir . "/" . $file);
            }
        }
        reset($files);
        rmdir($dir);
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文