PHP中mkdir('dir', 0777)实际权限为0755,因受系统umask(如0022)限制,真实权限=指定权限&(~umask);chmod()不受umask影响,推荐先mkdir再chmod实现精确权限控制。

PHP 的 mkdir() 传 0777 并不是“不能用”,而是它**根本达不到 0777 效果**——系统会按 umask 规则自动“砍掉”部分权限,最终生成的目录通常是 0755(Linux 默认 umask=0022),甚至更低。这不是 PHP 的 bug,而是 Unix/Linux 系统级的安全机制。
umask 是怎么“截权限”的
创建目录时,实际权限 = 指定权限 & (~umask)。
比如你写 mkdir('log', 0777),而当前 umask 是 0022(八进制),换算成二进制就是:
• 0777 → 111 111 111
• ~0022 → 111 101 101(取反)
• 与运算结果 → 111 101 101 → 八进制 0755
也就是说,umask 的本质是“屏蔽位”,它强制限制新建文件/目录的最大开放程度,防止误设高危权限。
为什么不该强行追求 0777
- 安全风险高:0777 表示所有用户(包括 web 服务器运行用户如 www-data、apache,以及同服务器其他账户)都能读、写、进入该目录,极易被恶意脚本篡改或植入
- 多数场景不必要:Web 应用通常只需让 PHP 进程(如 www-data)有写权限,其他用户保持只读或无权访问更合理
-
FTP 用户问题可另解:与其给整个目录 0777,不如用组权限(如
0775)+ 把 FTP 用户和 web 用户加到同一组,再配好setgid - 违反最小权限原则:这是系统安全的基本准则——只授予完成任务所必需的最低权限
更稳妥的替代方案
如果确实需要放宽权限(例如缓存目录供 FTP 清理),推荐以下做法:
立即学习“PHP免费学习笔记(深入)”;
- 用
0755或0775创建目录,再用chmod()单独补权限(注意chmod()不受 umask 影响) - 对多级目录,先
mkdir($path, 0755, true),再递归chmodr()(自定义函数或find . -type d -exec chmod 0755 {} \;) - 临时调整 umask:在 mkdir 前调用
umask(0),之后恢复原值(需注意线程/进程安全) - 改用系统命令:
exec("mkdir -m 0777 $path")(慎用,需校验路径防注入)
权限值写法必须注意
PHP 中权限必须用八进制整数,即以 0 开头、不带引号:
- ✅ 正确:
mkdir('cache', 0755)、chmod('cache', 0775) - ❌ 错误:
mkdir('cache', '0755')(字符串会被转成十进制 755 → 权限错乱) - ❌ 错误:
mkdir('cache', 755)(十进制 755 ≠ 八进制 0755)



















