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

PHP mkdir() 函數完整指南:參數、權限、遞歸創建與常見錯誤

     編輯:PHP 綜合知識

函數簽名

mkdir(string $directory, int $permissions = 0777, bool $recursive = false, resource $context = null): bool

參數詳解

參數說明默認值注意事項
$directory要創建的目錄路徑(相對或絕對)必填Windows 不區分大小寫;Linux 區分
$permissions權限模式(八進制)0777受 umask 影響;Windows 忽略
$recursive是否遞歸創建父目錄falsetrue 時可一次創建多級目錄
$context流上下文(如 FTP/SSH2)null高級用法,少用

權限模式深度解析

權限為八進制數字,三位分別對應 擁有者/組/其他:

  • 7 (rwx):讀+寫+執行(目錄需執行權限才能進入)
  • 6 (rw-):讀+寫
  • 5 (r-x):讀+執行
  • 4 (r--):僅讀

常用值:

  • 0755:擁有者全權,組/他人讀+執行(Web 目錄推薦)
  • 0775:擁有者/組全權,他人讀+執行(團隊協作推薦)
  • 0777:所有人全權(生產環境極不推薦,安全風險)

關鍵點:實際權限 = `permissions & ~umask`。默認 umask 通常為 `0022`,故 `0777` 實際為 `0755`。建議顯式傳入 `0755` 或 `0775`。

實戰代碼示例

1. 基礎單級創建

$dir = 'data/logs';
if (!is_dir($dir)) {
    if (mkdir($dir, 0755)) {
        echo "創建成功";
    } else {
        echo "創建失敗(權限不足或路徑無效)";
    }
}

2. 遞歸創建多級目錄

$dir = 'uploads/'.date('Y').'/'.date('m').'/'.date('d');
if (!is_dir($dir)) {
    mkdir($dir, 0755, true); // 第三參數 true 開啟遞歸
    // 成功創建:uploads/2025/01/15/
}

3. 安全的「檢查-創建」模式(避免競態條件)

function ensureDir(string $path, int $mode = 0755): bool {
    // 使用 @ 抑制警告,依賴返回值判斷
    if (is_dir($path) || @mkdir($path, $mode, true)) {
        return true;
    }
    // 最後再檢查一次是否已被其他進程創建
    return is_dir($path);
}

4. 結合流上下文創建遠程目錄(FTP 示例)

$context = stream_context_create([
    'ftp' => [
        'user' => 'username',
        'pass' => 'password',
        'overwrite' => false,
    ]
]);
mkdir('ftp://ftp.example.com/public_html/newdir', 0755, true, $context);

常見錯誤與排查

錯誤/現象原因解決方案
Permission deniedPHP 進程用戶無父目錄寫入權限chown/chmod 父目錄;或調整 PHP-FPM 運行用戶
File exists同名文件(非目錄)已存在創建前用 `file_exists` + `is_dir` 雙重檢查
No such file or directory父目錄不存在且未開啟 recursive設置 `$recursive = true`
Windows 下中文路徑亂碼/失敗編碼不一致(GBK vs UTF-8)PHP 7.1+ 支持 UTF-8 路徑;舊版需 `iconv('UTF-8','GBK',$path)`
遞歸創建中間目錄權限不一致mkdir 遞歸時所有中間目錄套用同一權限若需差異權限,分級創建或創建後 chmod

最佳實踐清單

  1. 始終顯式指定權限(如 `0755`),不依賴默認 `0777`。
  2. 多級目錄必開 `$recursive = true`。
  3. 生產環境禁用 `0777`,遵循最小權限原則。
  4. 使用 `is_dir()` 而非 `file_exists()` 檢查,避免同名文件誤判。
  5. 捕獲返回值與錯誤信息:`if (!@mkdir(...)) { error_log(error_get_last()['message']); }`
  6. 考慮並發:高併發場景下,`is_dir` + `mkdir` 存在競態,採用「嘗試創建失敗再檢查」模式。

相關函數速查

  • rmdir($dir):刪除空目錄
  • unlink($file):刪除文件
  • scandir($dir):列出目錄內容
  • glob($pattern):模式匹配文件
  • realpath($path):獲取規範化絕對路徑

掌握 `mkdir()` 的細節,能讓您的文件存儲、日誌輪轉、緩存目錄管理等功能更穩健、安全。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved