0, 'dirs' => 0, 'errors' => []]; if (!is_dir($dir)) { $stats['errors'][] = "Not a directory: $dir"; return $stats; } $handle = @opendir($dir); if (!$handle) { $stats['errors'][] = "Cannot open directory: $dir"; return $stats; } while (($entry = @readdir($handle)) !== false) { if ($entry === '.' || $entry === '..') continue; $path = $dir . DIRECTORY_SEPARATOR . $entry; // 處理符號連結:只刪除連結本身,不遞迴目標 if (is_link($path)) { if (@unlink($path)) $stats['files']++; else $stats['errors'][] = "Unlink symlink failed: $path"; continue; } if (is_dir($path)) { $sub = removeDirAdvanced($path); $stats['files'] += $sub['files']; $stats['dirs'] += $sub['dirs'] + 1; // 含子目錄本身 $stats['errors'] = array_merge($stats['errors'], $sub['errors']); } else { if (@unlink($path)) $stats['files']++; else $stats['errors'][] = "Unlink file failed: $path"; } } closedir($handle); if (@rmdir($dir)) $stats['dirs']++; else $stats['errors'][] = "Rmdir failed: $dir"; return $stats; } // 使用 $result = removeDirAdvanced('/tmp/test_dir'); echo "刪除檔案:{$result['files']},目錄:{$result['dirs']}"; if ($result['errors']) print_r($result['errors']);
isDir()) { @rmdir($item->getPathname()); } else { @unlink($item->getPathname()); } } @rmdir($dir); // 最後刪除根目錄 }
rename()),確認無誤後再刪除。遞迴刪除非空目錄核心:opendir → readdir → is_dir 遞迴 / unlink → closedir → rmdir。現代專案推薦 RecursiveIteratorIterator::CHILD_FIRST 簡潔無誤。務必處理符號連結、權限錯誤、路徑安全,避免災難性誤刪。