專案中常需動態建立上傳目錄、快取目錄等多層資料夾結構。PHP 內建 mkdir() 預設不支援遞迴建立(PHP 5 以前),且若目錄已存在會拋出警告。本文整理出穩健、可重複執行的建立邏輯。
<?php
/**
* 遞迴建立多層目錄,若目錄已存在則略過,不產生錯誤。
*
* @param string $base_path 基礎路徑(絕對或相對)
* @param array $sub_dirs 子目錄陣列,例如 ['tmp', 'qvod', 'cache']
* @param int $mode 權限,預設 0755
* @return bool 是否全部成功
*/
function ensure_dirs(string $base_path, array $sub_dirs, int $mode = 0755): bool
{
$current = rtrim($base_path, DIRECTORY_SEPARATOR);
foreach ($sub_dirs as $dir) {
$current .= DIRECTORY_SEPARATOR . $dir;
if (!is_dir($current)) {
// recursive=true 會自動建立父層;錯誤抑制器避免競態條件下的 warning
if (!@mkdir($current, $mode, true)) {
error_log("建立目錄失敗: $current");
return false;
}
}
}
return true;
}
// 使用範例
$root = __DIR__ . '/storage';
$dirs = ['tmp', 'qvod', 'logs', 'cache'];
ensure_dirs($root, $dirs);
project-root/
├── config/
│ └── paths.php // 定義 STORAGE_PATH 等常數
├── src/
│ └── Filesystem/
│ └── DirectoryManager.php // 封裝上述函式為服務類
├── storage/ // 執行期自動建立
│ ├── tmp/
│ ├── qvod/
│ └── logs/
└── vendor/
在服務容器中註冊 `DirectoryManager`,於應用啟動階段(如 Laravel 的 `AppServiceProvider::boot()`)呼叫 `ensureDirs()`,確保所有儲存路徑就緒。
原文摘自 cyuyan112233 專欄