权限充足时move_uploaded_file仍报Permission Denied问题求助
PHP move_uploaded_file 权限拒绝问题排查与解决方案
问题场景
运行PHP上传脚本时,尝试将/tmp目录的上传文件移动到项目内的
test/目录(绝对路径:/var/www/html/myproject/test),触发权限错误:move_uploaded_file(test/test.csv): failed to open stream: Permission denied in /var/www/html/myproject/import.php on line X, referer: http://192.168.1.1/myproject/import2.php脚本由apache用户运行,且apache是
test/目录的属主及属组成员,拥有rwx权限。
已完成排查
- safe_mode已禁用
- 未配置open_basedir
- file_uploads已开启
- upload_max_filesize为2MB,待上传文件约50KB,未超限
- post_max_size为8MB,请求远未达上限
- 使用绝对路径执行移动操作
is_dir("test/")返回trueis_writable("test/")返回false- PHP脚本内验证:待移动文件、
test/目录属主均为apache,文件权限600,目录权限755 - 通过
ps -aux | grep apache匹配Apache日志PID,确认进程以apache用户运行 getcwd()、__DIR__均返回正确目录/var/www/html/myprojectdirname(__FILE__)返回文件正确绝对路径file_exists($_FILES['file']['tmp_name'])返回true$_FILES['file']['error']返回0,上传无异常is_writable("/tmp")返回true- 临时对
test/执行chmod -R 777,仍提示权限拒绝且is_writable返回false - 临时禁用杀毒软件/EDR
test/安全上下文为unconfined_u:object_r:httpd_sys_content_t:s0,无异常- 未安装AppArmor、grsecurity等限制类安全软件
- 使用
fopen()/flock()确认待移动文件未被锁定 is_uploaded_file($_FILES['file']['tmp_name'])返回true
可行解决方向
调整SELinux上下文
httpd_sys_content_t为只读上下文,需改为可写的httpd_sys_rw_content_t:# 临时生效 chcon -R -t httpd_sys_rw_content_t /var/www/html/myproject/test # 永久生效 semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/html/myproject/test(/.*)?" restorecon -Rv /var/www/html/myproject/test检查父目录权限
确认/var/www/html/myproject目录对apache用户有执行权限(x),没有执行权限会导致无法进入子目录。验证PHP运行用户(PHP-FPM场景)
若使用PHP-FPM而非mod_php,进程实际运行用户可能不是apache,而是www-data或其他用户。查看PHP-FPM配置文件中的user和group字段,调整目录权限或FPM配置匹配。检查文件系统挂载属性
查看/var/www/html所在分区的挂载属性,确认是否存在noexec、nodev等限制:mount | grep /var/www/html尝试复制替代移动
临时文件的上下文或权限可能存在隐性限制,尝试复制文件后删除临时文件:$target = '/var/www/html/myproject/test/' . $_FILES['file']['name']; if (copy($_FILES['file']['tmp_name'], $target)) { unlink($_FILES['file']['tmp_name']); // 处理成功逻辑 } else { // 处理失败逻辑 }
内容的提问来源于stack exchange,提问作者Wild Droid
相关产品推荐
相关产品推荐

