mkdir() 默认目录存在时返回 false 并触发 E_WARNING;应先用 is_dir() 或 file_exists() 检查,再调用 mkdir($path, 0755, true),避免警告且准确处理权限、递归及父目录可写性问题。

PHP 的 mkdir() 在目标目录已存在时,**默认返回 false 并触发 E_WARNING 警告**,这不是错误,而是函数设计行为。直接忽略或压制警告(如加 @)会掩盖真实问题,也不利于调试。正确做法是:先检查再创建。
用 is_dir() 或 file_exists() 预判是否存在
这是最稳妥、最常用的方式。只有目录确实不存在时,才调用 mkdir():
-
is_dir($path)专用于判断是否为目录,语义清晰、性能略优 -
file_exists($path)更宽泛,能覆盖符号链接等,但若路径可能被文件占用,也建议用它 - 推荐组合写法:
if (!is_dir($path) && !mkdir($path, 0755, true)) { /* 创建失败处理 */ }
注意权限与递归参数必须匹配
即使目录不存在,mkdir() 仍可能因配置失败,导致你以为“是已存在”而误判。常见干扰项:
- 没加
true作为第三个参数 → 多级路径(如uploads/2026/11)必然失败,报No such file or directory,而非“已存在” - 权限掩码写成
755(十进制)而非0755(八进制)→ 实际权限被错误解析,可能导致创建后不可读,后续is_dir()检查失败 - 父目录不可写(如
/uploads所有者不是 Web 用户)→mkdir()返回false,但错误日志里是Permission denied,不是“已存在”
避免重复警告的干净写法
不依赖 @ 抑制,而是逻辑上规避:
立即学习“PHP免费学习笔记(深入)”;
$path = '/var/www/uploads/images';
if (!is_dir($path)) {
if (!mkdir($path, 0755, true)) {
throw new RuntimeException("无法创建目录: $path");
}
}这段代码不会触发任何警告,失败时可明确抛出异常或记录日志,便于定位是权限、路径还是磁盘问题。
批量创建时统一处理逻辑
如果要建多个目录(如按年月分类),把判断和创建封装成小函数更安全:
- 定义一个
ensureDir($path)函数,内部完成is_dir+mkdir(..., true)流程 - 对每个路径调用该函数,无需在循环里重复写判断逻辑
- 可选增加
chmod()补权(比如 mkdir 后发现权限被 umask 截断),但优先应设对初始0755和临时umask(0)



















