chmod() 修改文件权限必须用八进制整数,如0755而非755;需先检查文件存在性和目录可写性;Web服务器用户权限限制常致失败;递归修改需手动遍历,不可直接使用chmod -R。

chmod() 函数修改文件权限必须用八进制数
PHP 中改文件权限只能靠 chmod(),但它不接受字符串如 "755" 或 "rw-r-xr-x" —— 必须传八进制整数。写成 chmod($file, 755) 是错的,PHP 会当十进制 755 处理(对应八进制 1363),实际权限完全不对。
正确写法是加 0 前缀:chmod($file, 0755)。PHP 解析时才按八进制理解。也可以用 octdec() 转换,但没必要增加开销。
-
0644→ 所有者可读写,组和其他人只读 -
0755→ 所有者可读写执行,组和其他人可读执行 -
0600→ 仅所有者可读写(敏感配置文件推荐)
修改前务必检查文件是否存在且可访问
chmod() 不会自动创建文件,也不校验路径是否真实存在。如果传入不存在的路径,函数返回 false,但不会报错——容易误以为成功。
建议组合使用 file_exists() 和 is_writable()(注意:is_writable() 对目录和文件行为不同,对目录它检查是否有写权限+执行权限):
立即学习“PHP免费学习笔记(深入)”;
if (!file_exists($path)) {
throw new Exception("File not found: $path");
}
if (!is_writable(dirname($path))) {
throw new Exception("Cannot write to directory: " . dirname($path));
}
chmod($path, 0600);
Web 服务器用户权限限制常导致 chmod 失败
PHP 脚本运行在 Web 服务器用户下(如 www-data、apache 或 nginx),它只能修改自己拥有或所属组有权限的文件。如果文件属主是 root 且没开放组写权限,chmod() 必然失败。
常见现象:chmod() 返回 false,错误日志里出现 Operation not permitted 或静默失败。
- 确认文件当前属主:
ls -l $path - 临时调试可用
posix_getpwuid(posix_geteuid())查看 PHP 当前运行用户 - 生产环境避免让 PHP 直接改关键系统文件权限;应由部署脚本或运维通过
chown/chmod预置好
递归修改目录权限需手动遍历,chmod() 本身不支持
chmod() 只作用于单个文件或目录,不能像 shell 的 chmod -R 那样递归。想改整个目录树,得自己遍历:
$iterator = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, FilesystemIterator::SKIP_DOTS)
);
foreach ($iterator as $item) {
chmod($item->getPathname(), $mode);
}
但要注意:目录必须有执行权限(即 x 位)才能进入,所以给目录设 0755,文件设 0644,别一刀切全用 0755——否则可能让日志、缓存等可写文件变成可执行,引发安全风险。
真正需要递归改权限的场景极少,多数时候该用更细粒度的权限控制,比如只放开 cache/ 和 uploads/ 目录,其他保持严格只读。











