首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遞歸刪除整個目錄:基於 DirectoryIterator 的極簡實現

     編輯:PHP 綜合知識

前言

在文件管理、緩存清理、臨時目錄銷毀等場景中,需要將一個目錄及其所有子目錄、文件徹底刪除。PHP 的 SPL DirectoryIterator 提供了面向對象的目錄遍歷能力,配合遞歸即可實現極簡、可讀性強的刪除邏輯。

核心代碼

<?php
/**
 * 遞歸刪除目錄及其所有內容
 *
 * @param string $dir 目標目錄絕對路徑
 * @return bool 是否全部刪除成功
 */
function cleanup_directory(string $dir): bool
{
    if (!is_dir($dir)) {
        return false;
    }

    $iterator = new DirectoryIterator($dir);
    foreach ($iterator as $fileInfo) {
        // 跳過 . 和 ..
        if ($fileInfo->isDot()) {
            continue;
        }

        $pathname = $fileInfo->getPathname();

        if ($fileInfo->isDir()) {
            // 子目錄遞歸刪除
            cleanup_directory($pathname);
        } else {
            // 文件直接刪除
            @unlink($pathname);
        }
    }

    // 最後刪除空目錄本身
    return @rmdir($dir);
}

// 使用示例
cleanup_directory('/var/www/html/cache/temp');
?>

關鍵點解析

  1. DirectoryIterator 實現 Iterator 接口,可直接 foreach 遍歷。
  2. isDot() 用於過濾 .(當前目錄)和 ..(父目錄),避免無限遞歸。
  3. isDir() 區分目錄與文件,目錄需遞歸,文件直接 unlink()。
  4. 遞歸返回後,當前目錄已空,調用 rmdir() 刪除目錄本身。
  5. 使用 @ 抑制警告(如權限不足),生產環境建議改用 try-catch 或檢查返回值並記錄日誌。

進階版:帶異常處理與日誌

<?php
function cleanup_directory_safe(string $dir, array &$errors = []): bool
{
    if (!is_dir($dir)) {
        $errors[] = "目錄不存在:$dir";
        return false;
    }

    $iterator = new DirectoryIterator($dir);
    foreach ($iterator as $fileInfo) {
        if ($fileInfo->isDot()) continue;

        $path = $fileInfo->getPathname();
        try {
            if ($fileInfo->isDir()) {
                cleanup_directory_safe($path, $errors);
            } else {
                if (!unlink($path)) {
                    $errors[] = "刪除文件失敗:$path";
                }
            }
        } catch (Throwable $e) {
            $errors[] = "異常:{$e->getMessage()}($path)";
        }
    }

    if (!rmdir($dir)) {
        $errors[] = "刪除目錄失敗:$dir";
        return false;
    }
    return true;
}

$errors = [];
cleanup_directory_safe('/tmp/myapp_cache', $errors);
if ($errors) {
    error_log("清理異常:" . implode('; ', $errors));
}
?>

替代方案對比

方案優點缺點
DirectoryIterator 遞歸(本文)代碼清晰、面向對象、無額外依賴深層目錄可能觸發遞歸深度限制
RecursiveDirectoryIterator + RecursiveIteratorIterator (CHILD_FIRST)單次遍歷、無手動遞歸、效率略高代碼稍顯抽象,需理解 SPL 迭代器
system('rm -rf ' . escapeshellarg($dir))極快、一行代碼依賴 Shell、Windows 不通用、安全風險高
symfony/filesystem 或 league/flysystem跨平台、支援雲存儲、測試友好引入第三方依賴

總結

對於大多數 PHP 項目,DirectoryIterator 遞歸方案在可讀性、可維護性與性能之間取得了良好平衡。若目錄層級極深(超過 1000 層),建議改用 RecursiveIteratorIterator::CHILD_FIRST 非遞歸模式或成熟的文件系統抽象庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved