mkdir失败主因是权限不足、父目录缺失、umask干扰或路径超长;需用is_writable()验证、设recursive=true、用0755八进制权限、临时umask(0)或chmod()补权、Windows下防260字符限制。

mkdir 函数创建失败的常见报错
最常遇到的是 Warning: mkdir(): Permission denied 或 Warning: mkdir(): No such file or directory。前者说明父目录不可写或当前用户没权限;后者不是路径不存在,而是中间某级父目录压根没建——mkdir 默认不递归创建,这点和 shell 的 mkdir -p 完全不同。
实操建议:
- 检查目标路径的**父目录是否已存在**,且当前 PHP 进程(如 www-data、nginx 用户)对它有
write权限 - 用
is_writable()提前验证父目录可写性,别等mkdir报错才处理 - Linux 下注意 SELinux 或容器环境限制,有时权限看似正确但仍被拦截
递归创建多级目录必须加第三个参数
mkdir 第三个参数 $recursive 设为 true 才会逐级建父目录。不设或设为 false(默认值),哪怕路径是 /a/b/c,只要 /a/b 不存在,就直接失败。
示例对比:
立即学习“PHP免费学习笔记(深入)”;
// ❌ 失败:/tmp/foo/bar 不存在时,这行报错
mkdir('/tmp/foo/bar');
// ✅ 成功:自动创建 /tmp/foo 和 /tmp/foo/bar
mkdir('/tmp/foo/bar', 0755, true);
注意:0755 是八进制权限字面量,PHP 中必须写成 0755(开头带 0),写成 755 会被当十进制解析,结果完全不对。
权限掩码受 umask 影响,别以为设了 0777 就真能写
即使你传了 0777,实际创建的目录权限还会被系统 umask 值“砍掉”一部分。比如 umask 是 0022,mkdir('/x', 0777) 最终得到的是 0755(777 & ~022)。
实操建议:
- 用
umask(0)临时清空掩码再建目录(记得建完恢复原值) - 更稳妥的做法是建完立刻用
chmod()显式设权,绕过 umask 干扰 - 在 CLI 模式下 umask 通常比 Web 环境宽松,同一段代码 Web 下失败、CLI 下成功,大概率是 umask 差异
Windows 下路径分隔符和长路径限制
Windows 对反斜杠 支持良好,但 PHP 内部统一用正斜杠 / 处理路径,所以推荐统一用 /(如 C:/temp/mydir),避免双写 \ 出错。另外 Windows 默认限制 260 字符路径长度,超长时 mkdir 会静默失败。
应对方式:
- 用
realpath()或dirname()检查路径是否合法,而不是只信mkdir返回值 - 长路径启用需在 Windows 组策略中开启 “启用 Win32 长路径”,否则
mkdir对 >260 字符路径无能为力 - 跨平台代码优先用
dirname(__FILE__)拼接,少硬编码绝对路径
mkdir 都可能在你以为最稳的地方卡住。



















