PHP中mkdir()创建目录后必须调用chmod()才能确保权限准确,因为mkdir的mode参数受系统umask(如0022)影响,实际权限为0777 & ~0022 = 0755;而chmod不受umask限制,可精准设权,推荐先mkdir再chmod的两步法。

PHP中用mkdir()创建目录后,直接调用chmod()修改权限是最稳妥、最常用的做法。这是因为mkdir()指定的$mode参数常受系统umask影响,实际生成的权限往往比预期低(比如写0777却只得到0755)。先创建再显式chmod,能绕过umask干扰,确保权限准确生效。
为什么不能只靠mkdir()设权限
Linux/Unix系统默认有umask(如0022),它会按位取反后与你传入的$mode做AND运算。例如:mkdir('./data', 0777) → 实际权限 = 0777 & ~0022 = 0755
这就导致目录对组和其他用户缺少写权限,上传文件或写日志可能失败。
正确改权限的两步写法
- 先用
mkdir()创建目录(推荐开启$recursive = true支持多级) - 紧接着用
chmod()重新设置目标权限,不受umask影响
示例代码:
$path = './uploads/images/2026/11';
if (!is_dir($path)) {
if (mkdir($path, 0755, true)) {
chmod($path, 0755); // 显式加固权限
}
}
权限值怎么选才安全又实用
不建议无脑用0777,应按最小权限原则配置:
- 0755:所有者可读写执行,组和其他人仅读+执行——适合绝大多数Web可访问目录(如静态资源、缓存)
- 0700:仅所有者完全控制——适合含敏感配置或临时数据的私有目录
- 0775:所有者和组可读写执行,其他人只读执行——适合需要Web服务器与部署用户协同操作的场景(需确保两者同属一个组)
顺便注意几个易错点
-
chmod()返回布尔值,务必检查是否成功,失败通常因父目录无写权限或路径不存在 - 路径必须是真实存在的目录,否则
chmod()会静默失败 - Windows系统忽略
chmod()调用,该方案主要面向Linux/Unix服务器环境 - 如果目录由Web服务器用户(如www-data)创建,确保该用户对父目录有写权限,否则
mkdir()本身就会失败



















