PHP chmod() 函数
说明: chmod() 函数改变指定文件的权限模式。
语法
bool chmod ( string $filename , int $mode )
参数说明
| 参数 |
描述 |
| filename |
必需。要改变权限的文件路径 |
| mode |
必需。权限值,通常是一个八进制数 例如:0755、0644等 |
权限模式说明
八进制权限表示法
| 权限 |
数字 |
说明 |
| 只读 |
4 |
r-- |
| 只写 |
2 |
-w- |
| 只执行 |
1 |
--x |
| 读写 |
6 (4+2) |
rw- |
| 读执行 |
5 (4+1) |
r-x |
| 读写执行 |
7 (4+2+1) |
rwx |
常见权限示例
-
0755 - 所有者:读写执行,组和其他:读执行
-
0644 - 所有者:读写,组和其他:只读
-
0777 - 所有人:读写执行
-
0750 - 所有者:读写执行,组:读执行
-
0600 - 所有者:读写,其他:无权限
返回值
注意事项
- 只有文件所有者或超级用户(root)可以修改文件权限
- Windows 系统中此函数部分功能受限
- 权限值通常以八进制表示,前面要加0(如0755)
- 使用
clearstatcache() 清除文件状态缓存
- 注意安全风险,避免给文件过高的权限
示例
示例 1:基本使用
<?php
// 设置文件为所有者读写,其他只读
$filename = "test.txt";
if (chmod($filename, 0644)) {
echo "文件权限已成功修改为 0644";
} else {
echo "文件权限修改失败";
}
?>
示例 2:设置可执行权限
<?php
// 设置脚本文件为可执行
$script = "script.sh";
if (chmod($script, 0755)) {
echo "脚本已设置为可执行 (0755)";
} else {
echo "权限设置失败";
}
?>
示例 3:设置私有文件权限
<?php
// 设置配置文件为只有所有者可读写
$config = "config.php";
// 0600 表示所有者读写,其他无权限
if (chmod($config, 0600)) {
echo "配置文件已设置为私有 (0600)";
// 验证权限
$perms = fileperms($config);
echo "\n当前权限: " . decoct($perms & 0777);
} else {
echo "权限设置失败";
}
?>
示例 4:递归修改目录权限
<?php
/**
* 递归修改目录及其内容的权限
*/
function chmod_recursive($path, $filemode, $dirmode) {
if (!file_exists($path)) {
return false;
}
if (is_dir($path)) {
// 修改目录权限
if (!chmod($path, $dirmode)) {
return false;
}
// 遍历目录内容
$items = scandir($path);
foreach ($items as $item) {
if ($item == '.' || $item == '..') {
continue;
}
$itempath = $path . '/' . $item;
chmod_recursive($itempath, $filemode, $dirmode);
}
} else {
// 修改文件权限
return chmod($path, $filemode);
}
return true;
}
// 使用示例
$directory = '/var/www/html/temp';
$result = chmod_recursive($directory, 0644, 0755);
if ($result) {
echo "目录权限递归修改成功";
} else {
echo "权限修改失败";
}
?>
示例 5:获取和显示当前权限
<?php
function get_permissions_string($filename) {
if (!file_exists($filename)) {
return "文件不存在";
}
$perms = fileperms($filename);
// 判断类型
$type = '';
if (($perms & 0xC000) == 0xC000) $type = 's'; // Socket
elseif (($perms & 0xA000) == 0xA000) $type = 'l'; // 符号链接
elseif (($perms & 0x8000) == 0x8000) $type = '-'; // 普通文件
elseif (($perms & 0x6000) == 0x6000) $type = 'b'; // 块设备
elseif (($perms & 0x4000) == 0x4000) $type = 'd'; // 目录
elseif (($perms & 0x2000) == 0x2000) $type = 'c'; // 字符设备
elseif (($perms & 0x1000) == 0x1000) $type = 'p'; // 管道
else $type = 'u'; // 未知
// 所有者权限
$owner = (($perms & 0x0100) ? 'r' : '-');
$owner .= (($perms & 0x0080) ? 'w' : '-');
$owner .= (($perms & 0x0040) ? (($perms & 0x0800) ? 's' : 'x') : (($perms & 0x0800) ? 'S' : '-'));
// 组权限
$group = (($perms & 0x0020) ? 'r' : '-');
$group .= (($perms & 0x0010) ? 'w' : '-');
$group .= (($perms & 0x0008) ? (($perms & 0x0400) ? 's' : 'x') : (($perms & 0x0400) ? 'S' : '-'));
// 其他用户权限
$other = (($perms & 0x0004) ? 'r' : '-');
$other .= (($perms & 0x0002) ? 'w' : '-');
$other .= (($perms & 0x0001) ? (($perms & 0x0200) ? 't' : 'x') : (($perms & 0x0200) ? 'T' : '-'));
return $type . $owner . $group . $other . ' (' . decoct($perms & 0777) . ')';
}
// 使用示例
$file = 'example.php';
echo "文件: $file\n";
echo "权限: " . get_permissions_string($file);
?>
错误处理示例
<?php
function safe_chmod($filename, $mode) {
if (!file_exists($filename)) {
return ['success' => false, 'message' => '文件不存在'];
}
// 检查当前用户权限
$current_uid = posix_getuid();
$file_owner = fileowner($filename);
if ($current_uid != 0 && $current_uid != $file_owner) {
return ['success' => false, 'message' => '权限不足:只有文件所有者或root用户可以修改权限'];
}
// 验证权限模式
if (!is_int($mode) || $mode < 0 || $mode > 07777) {
return ['success' => false, 'message' => '无效的权限模式'];
}
// 尝试修改权限
if (chmod($filename, $mode)) {
clearstatcache();
return ['success' => true, 'message' => '权限修改成功'];
} else {
$error = error_get_last();
return ['success' => false, 'message' => '权限修改失败: ' . $error['message']];
}
}
// 使用示例
$result = safe_chmod('important.txt', 0600);
if ($result['success']) {
echo $result['message'];
} else {
echo "错误: " . $result['message'];
}
?>
相关函数
- 遵循最小权限原则:只给予必要的权限
- 配置文件保护:敏感配置文件应设置为 0600 或 0640
- 可执行文件:脚本文件通常设置为 0755
- 上传目录:设置为 0755,文件设置为 0644
- 清除缓存:修改权限后使用
clearstatcache()
- 错误处理:始终检查 chmod() 的返回值
- 权限验证:修改前后使用
fileperms() 验证