mkdir()递归创建目录必须传第三个参数true,否则多级路径会失败;权限参数0755在容器等环境可能受umask影响,需用chmod补全;is_dir()前须rtrim末尾斜杠以防误判。

mkdir() 第三个参数必须设为 true 才能递归创建
PHP 的 mkdir() 默认不支持递归,直接对不存在的父目录调用会失败并报 Warning: mkdir(): No such file or directory。必须显式传入第三个参数 true,否则哪怕路径里有好几层嵌套(比如 logs/2024/06/15),也会卡在第一级就中断。
常见错误写法:mkdir('logs/2024/06/15'); → 失败
正确写法:mkdir('logs/2024/06/15', 0755, true);
- 第二个参数是权限(八进制数,注意前面加
0,如0755) - 第三个参数
true表示递归创建所有缺失的上级目录 - Windows 下权限参数会被忽略,但
true仍必须传
用 is_dir() + mkdir() 组合避免重复创建警告
如果目录可能已存在,直接调用 mkdir() 会触发 Warning: mkdir(): File exists。不要依赖 @mkdir() 抑制错误——它掩盖真实问题,且无法区分“已存在”和“没权限”等不同失败原因。
更稳妥的做法是先检查:
立即学习“PHP免费学习笔记(深入)”;
if (!is_dir($path)) {
if (!mkdir($path, 0755, true)) {
throw new RuntimeException("Failed to create directory: $path");
}
}
-
is_dir()比file_exists()更准确:后者对文件也返回 true,而我们只关心目录 - 即使
mkdir()返回 false,也不代表完全失败(比如部分路径创建成功),所以检查返回值比单纯看 warning 更可靠
路径末尾斜杠会影响 is_dir() 判断结果
PHP 的 is_dir() 对末尾带斜杠的路径(如 'logs/')在某些系统(尤其是 Windows + 某些 PHP 版本)下可能返回 false,即使目录真实存在。这会导致误判、重复创建甚至报错。
解决方法统一用 rtrim($path, '/\\') 去掉末尾斜杠再判断:
$path = rtrim($path, '/\\');
if (!is_dir($path)) {
mkdir($path, 0755, true);
}
- 同时兼容 Unix 和 Windows 路径分隔符(
/和\) - 避免因路径格式不一致导致的逻辑分支错乱
- 尤其在拼接动态路径(如用户输入、配置项)时,这步不能省
权限 0755 在容器或共享主机中可能不生效
Linux 容器、Docker 或部分共享主机(如 cPanel)会受 umask 限制,即使你传了 0755,实际创建的目录权限可能是 0700 或 0750。这不是 PHP 错误,而是系统级行为。
验证方式:var_dump(substr(sprintf('%o', fileperms($path)), -4)); —— 查看真实权限
- 若需确保可读可执行,创建后可用
chmod($path, 0755)强制补全(注意:仅对当前目录有效,不递归) - 在 Docker 中,更推荐在构建镜像时用
RUN mkdir -p /var/log/app && chmod 755 /var/log/app预设权限 - 别指望
mkdir()在所有环境都精确还原你传的权限值
is_dir() 对末尾斜杠敏感——这些细节不处理,递归建目录看着简单,上线后却常在边缘 case 上出问题。











