PHP中mkdir()创建目录后权限不符合预期(如仅显示“d”)是因umask干预,必须用chmod()单独补设权限;正确做法是先mkdir($dir, 0755, true),再chmod($dir, 0755),权限值须为八进制整数0755,且需确保PHP进程用户对目录有写权限。

PHP 中用 mkdir() 创建目录后,如果权限不符合预期(比如只显示 d 而不是 drwxr-xr-x),说明系统 umask 干预了权限设置。此时必须用 chmod() 单独补设权限——这是最可靠、最通用的做法。
mkdir 后立即用 chmod 设置权限
mkdir() 的第二个参数(权限)只是“建议值”,实际创建的权限 = 指定值 & ~umask。例如 umask 是 0022,即使写 mkdir($path, 0777),最终也常变成 0755。所以不能依赖它一步到位。
正确做法是:先创建,再显式调用 chmod():
$dir = './uploads';
if (!is_dir($dir)) {
mkdir($dir, 0755, true); // 第三参数 true 允许递归创建父级
}
chmod($dir, 0755); // 强制覆盖为 0755,不受 umask 影响
- 权限值必须用八进制整数,写成
0755,不是"0755"或755 -
chmod()返回布尔值,失败时返回false,可加判断:if (!chmod($dir, 0755)) { error_log("Failed to set permissions on {$dir}"); }
注意目标目录的可写性与用户一致性
chmod() 能否成功,取决于 PHP 进程运行用户(如 www-data、apache 或 nobody)是否对目标目录有写权限(即能修改其元数据)。常见问题包括:
- 父目录权限太严(如
0700),导致 PHP 无法在其中创建子目录或修改权限 - SELinux 或 AppArmor 启用时拦截了 chmod 操作(Linux 服务器需检查
audit.log) - Web 服务器用户和 PHP 进程用户不一致(如 Nginx 用
nginx用户,PHP-FPM 却配成了www-data)
不同场景下的推荐权限值
根据用途选合适权限,避免过度开放:
- 仅 PHP 读写(如缓存目录):
0700(安全,但 Web 服务需以同一用户运行) - Web 可读 + PHP 可写(如上传目录):
0755(目录可列、可进入;文件一般设0644) - 需要 Web 写入(如 CMS 附件目录):
0775(配合组权限 + 正确chown :www-data) - 开发调试临时用:
0777(不建议上线环境使用)
font color="red">关键提醒:chmod 对目录生效,不影响已存在的子文件或子目录——如需递归设置,需自己遍历或改用 shell 命令(如 exec('chmod -R 0755 ' . escapeshellarg($dir)),但需确认禁用函数未限制)。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











