You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

权限充足时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/")返回true
  • is_writable("test/")返回false
  • PHP脚本内验证:待移动文件、test/目录属主均为apache,文件权限600,目录权限755
  • 通过ps -aux | grep apache匹配Apache日志PID,确认进程以apache用户运行
  • getcwd()、__DIR__均返回正确目录/var/www/html/myproject
  • dirname(__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

可行解决方向

  1. 调整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
    
  2. 检查父目录权限
    确认/var/www/html/myproject目录对apache用户有执行权限(x),没有执行权限会导致无法进入子目录。

  3. 验证PHP运行用户(PHP-FPM场景)
    若使用PHP-FPM而非mod_php,进程实际运行用户可能不是apache,而是www-data或其他用户。查看PHP-FPM配置文件中的user和group字段,调整目录权限或FPM配置匹配。

  4. 检查文件系统挂载属性
    查看/var/www/html所在分区的挂载属性,确认是否存在noexec、nodev等限制:

    mount | grep /var/www/html
    
  5. 尝试复制替代移动
    临时文件的上下文或权限可能存在隐性限制,尝试复制文件后删除临时文件:

    $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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 08:17:45