首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 綜合知識

PHP 遞歸創建多級目錄:一行代碼實現與最佳實踐

     編輯:PHP 綜合知識

核心函數

<?php
/**
 * 遞歸創建多級目錄
 * @param string $path 目標路徑(相對或絕對)
 * @param int    $mode 權限,默認 0755
 * @return bool 成功返回 true
 */
function ensure_dir(string $path, int $mode = 0755): bool {
    // PHP 5.0+ 內建遞歸參數,無需手寫遞歸
    return is_dir($path) || mkdir($path, $mode, true);
}

// 使用示例
ensure_dir('2007/3/4');           // 當前目錄下創建 2007/3/4
ensure_dir('/var/www/uploads/2024/05/15', 0775); // 絕對路徑

原理說明

mkdir($path, $mode, true) 第三個參數 $recursive = true 會自動創建父目錄,底層實現已處理併發競爭、權限繼承等邊界情況,強烈建議直接使用內建函數,勿重複造輪子。

手寫遞歸版(教學參考)

function createFolder_recursive(string $path, int $mode = 0755): bool {
    if (is_dir($path)) return true;
    $parent = dirname($path);
    if ($parent !== '.' && $parent !== '/' && !createFolder_recursive($parent, $mode)) {
        return false;
    }
    return @mkdir($path, $mode);
}

進階:併發安全的原子創建

高併發場景下,多進程同時調用 mkdir(..., true) 可能觸發 File exists 警告。解決方案:

function ensure_dir_atomic(string $path, int $mode = 0755): bool {
    if (is_dir($path)) return true;
    // 嘗試創建,忽略 EEXIST 錯誤
    $result = @mkdir($path, $mode, true);
    if ($result) return true;
    $error = error_get_last();
    // 併發導致目錄已存在,視為成功
    return $error && str_contains($error['message'], 'File exists') && is_dir($path);
}

權限最佳實踐

  • 目錄權限 0755(擁有者寫、組讀執行、其他讀執行)
  • 上傳目錄 0775 + 設置 setgid:chmod g+s uploads/,新文件自動繼承組
  • 敏感目錄 0700,僅擁有者可訪問
  • 避免 0777,除非臨時測試

常見坑點

現象原因解決
Permission denied父目錄無寫權限、或 Web 用戶非目錄擁有者chown www:www /path;chmod 755 父目錄
No such file or directory路徑中含特殊字符、或相對路徑基準錯誤使用絕對路徑 __DIR__ . '/../data'
File exists 警告併發創建同一目錄用 @ 抑制警告、或檢查 is_dir 後再創建
Windows 路徑分隔符代碼寫死 / 或 \用 DIRECTORY_SEPARATOR 或統一 /(PHP Windows 也支援)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved