php用fileperms获取权限再改_php取当前权限修改法【步骤】

7次阅读

fileperms返回的是十进制整数,但高位包含文件类型标志(如100表示普通文件),需用fileperms($path) & 0777提取纯权限值(如420对应0644),再进行位运算或chmod操作。

php用fileperms获取权限再改_php取当前权限修改法【步骤】

fileperms 返回的是十进制还是八进制?

fileperms 返回的是一个十进制整数,但它**代表的是底层 stat 结构中的 mode 字段**,包含文件类型(如 S_ifDIRS_IFREG)和权限位(如 S_IRUSR)。它不是你 ls -l 看到的三位八进制数(如 0755),也不能直接用 decoct() 转成“习惯上的权限字符串”就完事——因为高位还混着文件类型标志。

常见错误:直接 echo decoct(fileperms('test.txt')) → 得到类似 100644,开头的 100 是文件类型(普通文件),后面 644 才是权限。不剥离类型位,后续按位操作会出错。

  • 正确做法:用位与 & 清除文件类型位,只保留权限部分:fileperms($path) & 0777
  • 这样得到的就是纯权限值(如 420 对应 0644),可安全用于 chmod 或比较
  • 若要格式化显示为三位八进制字符串:sprintf('%03o', fileperms($path) & 0777)

如何安全地“取当前权限 + 修改某几位”?

直接读取再加减权限(比如 + 0004)极易出错——权限位是位掩码,不是算术值。必须用位运算:保留原权限,再用 | 设置位、& ~ 清除位。

例如:给文件加上“组可执行”,但不改动其他任何权限:

立即学习PHP免费学习笔记(深入)”;

```php $mode = fileperms($path) & 0777; // 取纯权限 $newMode = $mode | 0010;          // 设置组执行位(S_IXGRP) chmod($path, $newMode); ```
  • 要移除“其他可写”:用 $newMode = $mode & ~0002
  • 要同时设“所有者可读可写”且“清除其他执行”:$newMode = ($mode | 0600) & ~0001
  • 永远不要写 $mode + 0010 —— 若原权限已有该位,加法会溢出破坏其他位

chmod 第二个参数必须是八进制整数?

不是。PHP 的 chmod 接收的是整型权限值,**写成 07554930b111101101 都合法**,只要数值对就行。但实践中强烈建议用带前导 0 的八进制字面量(如 0755),原因有二:

  • 语义清晰:一眼看出是权限,而非随机整数
  • 避免十进制误写:比如本意是 0644,手误写成 644 → 实际传入的是十进制 644,等价于八进制 1204,远超常规权限范围,可能导致意外行为
  • 注意:0755 在 PHP 中是整数字面量,不是字符串;写成 '0755' 会触发类型转换警告,且结果不可控

为什么有时 chmod 失败但没报错?

chmod 返回布尔值,但失败常因权限不足(非 root 用户无法修改不属于自己的文件)、文件系统挂载为 noexec/nosuid、或路径是符号链接而未启用 follow 选项。尤其注意:

  • filepermschmod 对符号链接默认操作的是**链接本身**,不是目标文件。要改目标权限,需先 realpath() 或确保路径已解析
  • 某些共享主机禁用 chmod,此时函数返回 false,需显式检查:if (!chmod($path, $newMode)) { /* handle Error */ }
  • windows 下 chmod 仅模拟部分行为(主要影响只读属性),fileperms 返回值也受限,跨平台代码需规避强依赖

实际操作中最容易被跳过的,是 fileperms 返回值高位含文件类型这个事实——漏掉 & 0777 这一步,后面所有位运算都可能偏离预期。

text=ZqhQzanResources