mkdir(string $directory, int $permissions = 0777, bool $recursive = false, resource $context = null): bool
| 參數 | 說明 | 默認值 | 注意事項 |
|---|---|---|---|
| $directory | 要創建的目錄路徑(相對或絕對) | 必填 | Windows 不區分大小寫;Linux 區分 |
| $permissions | 權限模式(八進制) | 0777 | 受 umask 影響;Windows 忽略 |
| $recursive | 是否遞歸創建父目錄 | false | true 時可一次創建多級目錄 |
| $context | 流上下文(如 FTP/SSH2) | null | 高級用法,少用 |
權限為八進制數字,三位分別對應 擁有者/組/其他:
常用值:
0755:擁有者全權,組/他人讀+執行(Web 目錄推薦)0775:擁有者/組全權,他人讀+執行(團隊協作推薦)0777:所有人全權(生產環境極不推薦,安全風險)關鍵點:實際權限 = `permissions & ~umask`。默認 umask 通常為 `0022`,故 `0777` 實際為 `0755`。建議顯式傳入 `0755` 或 `0775`。
$dir = 'data/logs';
if (!is_dir($dir)) {
if (mkdir($dir, 0755)) {
echo "創建成功";
} else {
echo "創建失敗(權限不足或路徑無效)";
}
}
$dir = 'uploads/'.date('Y').'/'.date('m').'/'.date('d');
if (!is_dir($dir)) {
mkdir($dir, 0755, true); // 第三參數 true 開啟遞歸
// 成功創建:uploads/2025/01/15/
}
function ensureDir(string $path, int $mode = 0755): bool {
// 使用 @ 抑制警告,依賴返回值判斷
if (is_dir($path) || @mkdir($path, $mode, true)) {
return true;
}
// 最後再檢查一次是否已被其他進程創建
return is_dir($path);
}
$context = stream_context_create([
'ftp' => [
'user' => 'username',
'pass' => 'password',
'overwrite' => false,
]
]);
mkdir('ftp://ftp.example.com/public_html/newdir', 0755, true, $context);
| 錯誤/現象 | 原因 | 解決方案 |
|---|---|---|
| Permission denied | PHP 進程用戶無父目錄寫入權限 | 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 |
rmdir($dir):刪除空目錄unlink($file):刪除文件scandir($dir):列出目錄內容glob($pattern):模式匹配文件realpath($path):獲取規範化絕對路徑掌握 `mkdir()` 的細節,能讓您的文件存儲、日誌輪轉、緩存目錄管理等功能更穩健、安全。