文件系統操作中,遞歸掃描目錄樹、批量刪除文件/目錄是常見需求(如緩存清理、上傳目錄維護)。本文提供兩個封裝良好的工具類:目錄遍歷器與遞歸刪除器。
<?php
/**
* 遞歸刪除指定目錄及其所有子目錄、文件
* @param string $path 目錄絕對路徑
* @return bool 成功返回 true,失敗返回 false
*/
function recursiveDelete(string $path): bool {
// 1. 判斷目錄是否存在
if (!file_exists($path)) {
return false;
}
// 2. 讀取目錄內容
$list = scandir($path);
// 3. 遍歷處理
foreach ($list as $item) {
// 跳過 . 和 ..
if ($item === '.' || $item === '..') continue;
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
// 4. 文件直接刪除,目錄遞歸
if (is_file($fullPath)) {
unlink($fullPath);
} elseif (is_dir($fullPath)) {
recursiveDelete($fullPath);
}
}
// 5. 最後刪除空目錄本身
return rmdir($path);
}
// 使用示例
recursiveDelete('/var/www/cache/temp');
?>
<?php
/**
* 目錄樹遍歷器
*/
class DirectoryScanner {
/**
* 遞歸掃描並輸出所有路徑
* @param string $path 起始目錄
* @return void
*/
public function scan(string $path): void {
if (!file_exists($path)) {
return;
}
$list = scandir($path);
foreach ($list as $item) {
if ($item === '.' || $item === '..') continue;
$fullPath = $path . DIRECTORY_SEPARATOR . $item;
echo $fullPath . PHP_EOL; // 或收集到陣列
if (is_dir($fullPath)) {
$this->scan($fullPath); // 遞歸
}
}
}
}
// 使用示例
$scanner = new DirectoryScanner();
$scanner->scan('D:/www/project/storage');
?>
is_writable(),避免權限不足報錯。try-catch 捕獲 RuntimeException,記錄失敗路徑。RecursiveDirectoryIterator + RecursiveIteratorIterator 替代遞歸函數,避免棧溢出並支援過濾:$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST // 先刪除文件再刪目錄
);
foreach ($iterator as $file) {
$file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
}
rmdir($path);
基礎遞歸函數適合中小型目錄;生產環境大規模操作推薦使用 SPL 迭代器配合異步任務隊列,並加入日誌記錄與錯誤重試機制。