mkdir() 是 PHP 建立目錄的核心函式,語法為 mkdir(string $directory, int $permissions = 0777, bool $recursive = false, resource $context = null): bool。本文將詳細解析權限模式、遞迴建立、Windows/Linux 差異與錯誤處理最佳實踐。
| 參數 | 型別 | 預設值 | 說明 |
|---|---|---|---|
$directory | string | - | 目錄路徑,相對或絕對路徑 |
$permissions | int | 0777 | 八進位權限模式 (如 0755),Windows 下被忽略 |
$recursive | bool | false | true 時遞迴建立父目錄 (PHP 5.0.0+) |
$context | resource | null | 串流上下文 (PHP 5.0.0+) |
權限採用八進位三位數,對應 擁有者/群組/其他人 三類身分:
權限碼 二進位 意義 4 100 讀取 2 010 寫入 1 001 執行/進入目錄 常用組合: 0755 = rwxr-xr-x (擁有者全權,群組/其他可讀可進入) 0777 = rwxrwxrwx (所有人全權,預設值) 0700 = rwx------ (僅擁有者可存取,最高安全性)
<?php
// 簡單建立 (使用預設 0777)
if (mkdir("temp")) {
echo "目錄建立成功";
}
// 指定權限建立
if (mkdir("private", 0700)) {
echo "私有目錄建立成功 (僅擁有者可存取)";
}
// 遞迴建立多層目錄 (PHP 5.0+)
if (mkdir("data/users/2024/01", 0755, true)) {
echo "多層目錄遞迴建立成功";
}
?>
| 特性 | Linux/Unix | Windows |
|---|---|---|
| 權限模式 | 完整支援 | 被忽略 |
| 路徑分隔符 | / | \ 或 / 皆可 |
| 大小寫敏感 | 是 | 否 |
| 預設 umask 影響 | 是 (實際權限 = mode & ~umask) | 否 |
| 錯誤 | 常見原因 | 解決方案 |
|---|---|---|
| Permission denied | 父目錄無寫入權限 | chmod 父目錄、更換擁有者、調整 PHP 執行身分 |
| File exists | 同名檔案/目錄已存在 | 先用 is_dir()/file_exists() 檢查 |
| No such file or directory | 父目錄不存在且未啟用 recursive | 啟用 recursive=true 或手動建立父目錄 |
| Invalid path | 路徑含非法字元或過長 | 驗證路徑格式、縮短路徑層級 |
<?php
function getTempDir($prefix = 'app_') {
$base = sys_get_temp_dir() . '/' . $prefix . bin2hex(random_bytes(8));
mkdir($base, 0700, true); // 僅擁有者可存取
return $base;
}
// 使用後記得清理
$tempDir = getTempDir();
// ... 處理檔案 ...
// 清理函式
function removeDirRecursive($dir) {
if (!is_dir($dir)) return;
$files = array_diff(scandir($dir), ['.', '..']);
foreach ($files as $file) {
$path = $dir . '/' . $file;
is_dir($path) ? removeDirRecursive($path) : unlink($path);
}
rmdir($dir);
}
?>
<?php
function ensureUserUploadDir($userId) {
$base = "/var/www/uploads/users/{$userId}";
$dirs = [
$base,
"{$base}/images",
"{$base}/documents",
"{$base}/temp"
];
foreach ($dirs as $dir) {
if (!is_dir($dir)) {
mkdir($dir, 0750, true); // 群組可讀,其他不可存取
// 設定群組擁有權 (需 root 權限)
// chgrp($dir, 'www-data');
}
}
return $base;
}
?>
fileperms() 確認 umask 影響後的實際權限mkdir() 雖然簡單,但權限模式、遞迴建立、跨平台差異、錯誤處理等細節決定了應用的健壯性。掌握 八進位權限計算、善用 recursive 參數、理解 umask 影響、建立完善的 錯誤處理流程,是 PHP 後端開發者的必修功課。