mkdir() 預設僅建立單層目錄,若父目錄不存在會失敗。本文詳細說明 mkdir() 參數、遞迴建立多層目錄的自訂函式實作、以及對應的遞迴刪除目錄函式。
mkdir(string $directory, int $permissions = 0777, bool $recursive = false, ?resource $context = null): bool
$directory:目錄路徑。$permissions:權限模式 (八進位),預設 0777 (受 umask 影響)。$recursive:PHP 5.0.0+ 設為 true 可自動建立父目錄,強烈建議直接使用此參數。$context:串流上下文。<?php
// 一行搞定多層目錄建立
mkdir('div/css/layout', 0777, true); // true = recursive
?>
這是官方推薦、最高效、最簡潔的做法,無需自寫遞迴函式。
<?php
/**
* 相容舊版 PHP 的多層目錄建立 (PHP 4 風格)
*/
function mkdirs(string $dir, int $mode = 0777): bool {
if (is_dir($dir)) return true;
// 遞迴建立父目錄
$parent = dirname($dir);
if ($parent !== '.' && $parent !== '/' && !mkdirs($parent, $mode)) {
return false;
}
return @mkdir($dir, $mode); // @ 抑制已存在警告
}
// 使用
mkdirs('div/css/layout');
<?php
/**
* 遞迴刪除目錄及其所有內容
*/
function rmdirs(string $dir): bool {
if (!is_dir($dir)) return false;
$items = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($items as $item) {
if ($item->isDir()) {
rmdir($item->getPathname());
} else {
unlink($item->getPathname());
}
}
return rmdir($dir);
}
// 使用
rmdirs('div/css/layout');
優點:使用 SPL 迭代器 CHILD_FIRST 確保先刪除子項再刪除父目錄,程式碼簡潔無手寫遞迴 Bug 風險。
function rmdirs_legacy($dir) {
$d = dir($dir);
while (false !== ($child = $d->read())) {
if ($child !== '.' && $child !== '..') {
$path = $dir . DIRECTORY_SEPARATOR . $child;
is_dir($path) ? rmdirs_legacy($path) : unlink($path);
}
}
$d->close();
return rmdir($dir);
}
0777 受 umask 影響,實際權限通常為 0755 (目錄) / 0644 (檔案)。www-data) 必須對父目錄有寫入權限。$safe = basename($input); mkdir("/var/www/uploads/$safe", 0755, true);PHP 5.0+ 直接使用 mkdir($path, 0777, true) 即可建立多層目錄,簡潔高效。刪除目錄樹推薦使用 SPL RecursiveIteratorIterator::CHILD_FIRST 模式,程式碼極短且正確。舊版相容或教學需求可參考手寫遞迴實作。