在寫入快取、日誌或使用者上傳檔案時,常需自動建立多層巢狀目錄。雖然現代語言均提供內建函式(Python os.makedirs()、PHP mkdir($path, 0777, true)),但理解遞迴實現原理有助於處理特殊場景(如自定義權限、跨平台路徑處理、舊版本相容)。本文對比 Python 與 PHP 的遞迴建立目錄邏輯。
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os
def mkFolder(path: str) -> None:
\"\"\"遞迴建立多層目錄(相容舊版 Python)\"\"\"
# 移除尾部斜線,避免 dirname 回傳空字串導致無限遞迴
path = path.rstrip('/\\\\')
if not os.path.exists(path):
# 先建立父目錄
parent = os.path.dirname(path)
if parent and not os.path.exists(parent):
mkFolder(parent)
# 建立當前目錄
try:
os.mkdir(path, 0o755)
print(f'已建立目錄: {path}')
except OSError as e:
print(f'建立失敗 {path}: {e}')
# 測試
if __name__ == '__main__':
mkFolder('./google/baidu/yahoo/sougou/')
rstrip('/\\\\') 移除尾部斜線,防止 os.path.dirname('a/b/') 回傳 'a/b' 而非 'a',導致遞迴終止條件失效。if not os.path.exists(path) 確保不重複建立。0o755 八進位模式(擁有者讀寫執行,群組/其他讀執行)。<?php
function mkFolder(string $path): void {
// 正規化路徑:移除尾部斜線,統一分隔符
$path = rtrim($path, '/\\\\');
$path = str_replace('\\\\', '/', $path);
if (!is_dir($path)) {
// 遞迴建立父目錄
$parent = dirname($path);
if ($parent !== '.' && $parent !== '/') {
mkFolder($parent);
}
// 建立當前目錄
if (!mkdir($path, 0777, true)) { // PHP 5.0+ 第三參數 recursive=true 可直接建立多層
// 若環境不支援 recursive 參數,需手動遞迴(如上邏輯)
error_log("無法建立目錄: {$path}");
} else {
echo "已建立目錄: {$path}\n";
}
}
}
// 測試
mkFolder('./google/baidu/yahoo/sougou/');
?>
mkdir($path, $mode, true) 第三參數 recursive=true 可直接建立多層目錄,無需手寫遞迴。/,Windows 亦可識別。| 維度 | Python | PHP |
|---|---|---|
| 內建多層建立 | os.makedirs(path, exist_ok=True) (Py 3.2+) | mkdir(path, 0777, true) (PHP 5.0+) |
| 手動遞迴核心 | os.path.dirname() + os.mkdir() | dirname() + mkdir() |
| 路徑分隔符處理 | os.path.join() 自動適配 | 建議統一用 / |
| 權限模式 | 八進位 0o755 | 八進位 0777(受 umask 影響) |
| 錯誤處理 | try/except 捕獲 OSError | 檢查回傳值 + error_get_last() |
EEXIST 錯誤。0755,避免 0777 帶來安全風險。兩種語言的遞迴邏輯驚人相似,核心皆為「先建父,再建子」。掌握此模式,不僅能應對舊環境限制,更能深入理解檔案系統操作本質。現代開發請直接使用內建的多層建立函式,將精力集中在業務邏輯上。