要刪除一個非空目錄,必須先遞歸清空其內部所有檔案與子目錄,最後才能移除該目錄本身。PHP 沒有內建「強制刪除目錄」的單一函數,需自行實作遞歸邏輯。
<?php
/**
* 遞歸刪除目錄及其所有內容
* @param string $dir 目標目錄路徑
* @return bool 刪除成功返回 true
*/
function deleteDirectory(string $dir): bool {
// 確保路徑以斜線結尾
$dir = rtrim($dir, '/') . '/';
if (!is_dir($dir)) {
return false;
}
$dh = opendir($dir);
if ($dh === false) {
return false; // 無法開啟目錄(權限不足等)
}
while (($file = readdir($dh)) !== false) {
// 跳過當前目錄與上層目錄
if ($file === '.' || $file === '..') {
continue;
}
$fullPath = $dir . $file;
if (is_dir($fullPath)) {
// 遞歸刪除子目錄
deleteDirectory($fullPath);
} else {
// 刪除檔案
@unlink($fullPath); // 加 @ 抑制警告,實際專案建議改用錯誤處理
}
}
closedir($dh);
// 最後刪除空目錄
return @rmdir($dir);
}
// 使用範例
$targetDir = "./fakeDir";
if (deleteDirectory($targetDir)) {
echo "目錄 {$targetDir} 及其內容已成功刪除。";
} else {
echo "刪除失敗:目錄不存在或權限不足。";
}
?>
. 和 .. 必須排除,否則會陷入無限遞歸。is_dir() 區分,檔案用 unlink(),目錄遞歸呼叫自身。closedir() 釋放目錄控制代碼,防止資源洩漏。@ 抑制警告,生產環境建議改用 try-catch 或檢查返回值並記錄日誌。若專案環境允許,可使用 RecursiveDirectoryIterator 搭配 FilesystemIterator 實作更物件導向的寫法:
<?php
function deleteDirectoryModern(string $dir): void {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $item) {
$item->isDir() ? rmdir($item->getPathname()) : unlink($item->getPathname());
}
rmdir($dir);
}
?>
遞歸刪除是檔案系統操作的基礎功能,掌握其原理有助於建立更健壯的檔案管理模組。