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

PHP 刪除非空目錄遞迴函數三種寫法比較

     編輯:PHP 綜合知識

PHP 遞迴刪除非空目錄完整實作

rmdir() 僅能刪除空目錄,刪除含檔案/子目錄的資料夾需先遞迴清空內容。以下提供三種寫法,從基礎到進階。

寫法一:標準遞迴(最易理解)

<?php
function deleteDirRecursive($dir) {
    if (!is_dir($dir)) {
        return false;
    }
    $handle = opendir($dir);
    while (($file = readdir($handle)) !== false) {
        if ($file === '.' || $file === '..') continue;
        $path = $dir . DIRECTORY_SEPARATOR . $file;
        if (is_dir($path)) {
            deleteDirRecursive($path); // 遞迴刪除子目錄
        } else {
            unlink($path); // 刪除檔案
        }
    }
    closedir($handle);
    return rmdir($dir); // 刪除空目錄本身
}

// 使用
if (deleteDirRecursive('./temp')) {
    echo '刪除成功';
} else {
    echo '刪除失敗';
}

寫法二:使用 FilesystemIterator(PHP 5.3+,物件導向、自動跳過 . 與 ..)

<?php
function deleteDirIterator($dir) {
    if (!is_dir($dir)) return false;
    
    foreach (new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS) as $item) {
        if ($item->isDir()) {
            deleteDirIterator($item->getPathname());
        } else {
            $item->unlink(); // SplFileInfo::unlink()
        }
    }
    return rmdir($dir);
}

寫法三:使用 RecursiveDirectoryIterator + RecursiveIteratorIterator(最簡潔,底層處理遞迴順序)

<?php
function deleteDirRecursiveIterator($dir) {
    if (!is_dir($dir)) return false;
    
    $files = new RecursiveIteratorIterator(
        new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
        RecursiveIteratorIterator::CHILD_FIRST // 關鍵:先處理子項,再處理父目錄
    );
    
    foreach ($files as $file) {
        if ($file->isDir()) {
            rmdir($file->getPathname());
        } else {
            unlink($file->getPathname());
        }
    }
    return rmdir($dir);
}

三種寫法比較

特性寫法一 opendir寫法二 FilesystemIterator寫法三 RecursiveIterator
PHP 版本需求4.0+5.3+5.3+
程式碼長度較長中等最短
可讀性高(教學用)高中(需理解迭代器)
效能基準略好最好(C 層實作)
錯誤處理手動例外處理例外處理
符號連結處理需自行判斷預設跟隨預設跟隨

進階:錯誤處理與符號連結安全

<?php
function safeDeleteDir($dir) {
    $dir = realpath($dir); // 解析符號連結,避免刪除連結目標外的檔案
    if (!$dir || !is_dir($dir)) return false;
    
    // 防止刪除系統關鍵目錄
    $protected = ['/', '/home', '/var', '/etc', '/usr', __DIR__];
    if (in_array($dir, $protected)) {
        trigger_error("嘗試刪除受保護目錄: $dir", E_USER_WARNING);
        return false;
    }
    
    try {
        return deleteDirRecursiveIterator($dir);
    } catch (Exception $e) {
        error_log("刪除目錄失敗 $dir: " . $e->getMessage());
        return false;
    }
}

使用建議

  • 現代專案(PHP 7.1+)優先使用 寫法三,程式碼最少、效能最好。
  • 需相容舊版 PHP 專案用 寫法一。
  • 生產環境務必加入 路徑驗證、權限檢查、例外處理、日誌記錄。
  • 大量檔案刪除考慮背景任務(Queue Worker)避免逾時。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved