<?php
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
$path = $dir . '/' . $object;
if (is_dir($path)) {
rrmdir($path); // 遞歸刪除子目錄
} else {
unlink($path); // 刪除文件
}
}
}
reset($objects); // 重置指標(非必需)
rmdir($dir); // 刪除空目錄
}
}
?>
<?php
function deleteAll($directory, $empty = false) {
// 規範化路徑
if (substr($directory, -1) === '/') {
$directory = substr($directory, 0, -1);
}
if (!file_exists($directory) || !is_dir($directory)) return false;
if (!is_readable($directory)) return false;
$handle = opendir($directory);
while (($entry = readdir($handle)) !== false) {
if ($entry === '.' || $entry === '..') continue;
$path = $directory . '/' . $entry;
if (is_dir($path)) {
deleteAll($path); // 遞歸刪除子目錄
} else {
unlink($path);
}
}
closedir($handle);
if ($empty === false) {
return rmdir($directory);
}
return true;
}
?>
<?php
function deleteDirectory($dir) {
if (!file_exists($dir)) return true;
if (!is_dir($dir) || is_link($dir)) return unlink($dir);
foreach (scandir($dir) as $item) {
if ($item === '.' || $item === '..') continue;
$path = $dir . '/' . $item;
if (!deleteDirectory($path)) {
// 權限不足嘗試修復
chmod($path, 0777);
if (!deleteDirectory($path)) return false;
}
}
return rmdir($dir);
}
?>
| 版本 | 特點 | 適用場景 |
|---|---|---|
| rrmdir() | 簡潔、標準遞歸 | 一般用途、權限正常環境 |
| deleteAll() | 可選僅清空、opendir/readdir 兼容舊版 | 需保留目錄、舊 PHP 版本 |
| deleteDirectory() | 自動 chmod 重試、處理符號鏈接 | 權限複雜、需刪除用戶上傳目錄 |
is_link() 檢測並用 unlink() 刪除鏈接本身,而非目標。rmdir() 要求目錄為空,且無文件被佔用。max_execution_time 或棧溢出,考慮迭代隊列實現。rmdir() 可操作遠程目錄(需權限)。<?php
function rrmdir_spl($dir) {
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($iterator as $file) {
$file->isDir() ? rmdir($file->getPathname()) : unlink($file->getPathname());
}
rmdir($dir);
}
?>
CHILD_FIRST 確保先刪除子項再刪除父目錄,代碼更簡潔、無遞歸深度限制。