mkdir() 报 permission denied 最常见原因是 php 进程用户对目标路径的直接父目录无写权限;报 no such file or directory 是因未启用递归创建(缺第三个参数 true);权限不符是 umask 位运算导致,应创建后用 chmod() 显式设权。

mkdir() 报 Permission denied:先确认 PHP 进程用户对父目录有写权限
失败最常见原因不是代码写错,而是 PHP 运行用户(如 www-data、nginx 或容器里的 apache)对目标路径的**直接父目录**没有 write 权限。比如要创建 uploads/images/2024/06,哪怕 uploads 已存在,只要它属主是 root 且权限是 755,www-data 就无法在其中新建 images 子目录。
验证方式很简单:
- 用
ls -ld /var/www/html/uploads看属主和权限;输出中第二列应为www-data或你 PHP 进程所属组,第三列需含w(如drwxr-xr-x中的第二个x不代表可写,要看中间三位:rwx才表示属主可写) - 在 PHP 里用
is_writable(dirname($path))替代is_dir()判断——后者对权限不足的已存在目录也返回false,容易误判 - Docker 环境下必须在
Dockerfile的COPY后加RUN chown -R www-data:www-data /var/www,不能靠chmod 777补救
mkdir() 创建了目录但权限不对:umask 正在悄悄改你的 0755
你写了 mkdir('log', 0755, true),结果 ls -l 看到的是 drwxr-x---(即 750),这不是 bug,是系统 umask 在生效。PHP 调用 mkdir(2) 系统调用时,内核会把传入的 mode 和当前进程的 umask 做位运算:final_mode = mode & ~umask。
典型表现:
- Linux 默认
umask是0022,所以0755 & ~0022 = 0733→ 实际得drwx-wx-wx(注意:属组和其他用户的r被拿掉了) -
0777写出来也没用,照样被砍;而且八进制必须写成0777,写成777会被当十进制处理(等于01411八进制,完全不是你想要的) - 不要在生产环境全局
umask(0)—— 多线程 Web 服务器中它会跨请求污染,且不安全 - 稳妥做法是创建后立刻
chmod($path, 0755),或只对关键路径这么做
mkdir() 报 No such file or directory:递归参数没开,或路径含非法字符
错误信息是 Warning: mkdir(): No such file or directory,说明 PHP 默认只建最后一级,前面所有父目录都得手动存在。这不是权限问题,是调用方式问题。
必须显式传第三个参数 true:
- 错:
mkdir('a/b/c')—— 即使a存在,a/b缺失就失败 - 对:
mkdir('a/b/c', 0755, true)—— 会依次建a→a/b→a/b/c - 第二个参数(权限)不能省略,尤其 Linux 下不传会受
umask影响更大;Windows 忽略权限但建议保留以保跨平台 - 路径含中文或 Unicode 字符时,确保脚本文件保存为 UTF-8 无 BOM,且系统 locale 支持(如
en_US.UTF-8),否则mkdir()可能静默失败
重复调用 mkdir() 触发 warning:别用 @ 抑制,要主动防御
多次执行 mkdir('cache'),第二次就会报 Warning: mkdir(): File exists。@ 抑制只是掩盖问题,还会让真正该报错的地方也被吞掉。
正确姿势是前置判断:
- 用
is_dir($path),不是file_exists($path)—— 后者对同名文件也返回true,逻辑错乱 - 但注意:
is_dir()对权限不足的已存在路径也返回false,所以更健壮的写法是:if (!is_dir($path) && !is_writable(dirname($path))) { /* 报错 */ } - 如果目录结构复杂(如按日期哈希分层),建议用
dirname()循环向上检查每一级,或用RecursiveDirectoryIterator配合mkdir构建容错逻辑
真正卡住人的从来不是语法,而是权限归属、umask 掩码、用户上下文这三者交织的现实约束。写完 mkdir() 后多跑一句 ls -ld 看实际属主和权限,比反复改 PHP 代码快得多。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











