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

PHP/IIS环境下file_get_contents读取上传文件遇权限拒绝问题求助

PHP上传文件后file_get_contents权限拒绝问题排查与解决

问题场景

文件成功上传至.../upload/tm/目录后,调用file_get_contents读取时触发500错误:权限拒绝。核心代码如下:

$target = 'upload/' . $data['folder'] . '/' . $filename;
if (move_uploaded_file($file[$data['name']]['tmp_name'], $target)) {
    // $success = true;
    chmod($target, 0755);
}

已调研情况

  • 临时文件移动到目标目录时,不会继承.../upload/tm/的权限,而是保留c:\windows\temp的权限配置
  • 已确认c:\windows\temp和.../upload/tm/的权限列表:IUSR、IIS_IUSRS、localmachine$、localmachine$/users等指定用户均拥有相同读写权限
  • 手动重新应用.../upload/tm/中IUSR的继承权限可临时解决,但无法作为长期自动化方案

临时 workaround(更新)

将临时上传文件夹改为网站目录树分支后,文件可正常访问读取。但仍希望保留原临时文件夹路径,需明确两个问题:

  1. 为何权限配置看似一致,file_get_contents仍无法读取?
  2. 如何在保留原临时文件夹路径的前提下彻底解决?

原因分析

  1. Windows权限的隐性差异:表面权限列表相同不代表有效权限一致:
    • c:\windows\temp是系统目录,权限受UAC、系统安全策略限制,部分用户权限是通过组间接继承,移动文件后这些间接权限不会被携带
    • IIS运行在应用池身份(默认是IIS AppPool\应用池名称),而你检查的用户列表里大概率没包含这个核心身份——这才是PHP实际的运行身份
  2. move_uploaded_file的Windows特性:跨目录树移动文件时,不会自动应用目标目录的权限继承规则,而是保留源文件的DACL(自由访问控制列表)。如果源文件的DACL不包含PHP运行身份的读取权限,就会触发拒绝

解决方案

方案1:修复目标目录权限继承(推荐)

给.../upload/tm/配置强制权限继承,并确保应用池身份拥有读取权限:

  • 右键upload/tm目录 → 属性 → 安全 → 高级
  • 勾选「替换所有子对象权限继承的权限条目」,点击应用
  • 添加IIS AppPool\[你的应用池名称]用户,授予读取&执行、列出文件夹内容、读取权限
  • 代码中移除chmod(0755)(Windows下chmod仅部分生效,优先依赖系统权限配置)

方案2:用复制替代移动

放弃move_uploaded_file,改用copy()+unlink()组合,复制文件会自动应用目标目录的权限继承:

$target = 'upload/' . $data['folder'] . '/' . $filename;
if (copy($file[$data['name']]['tmp_name'], $target)) {
    unlink($file[$data['name']]['tmp_name']); // 清理临时文件
}

注意:需要确保临时目录和目标目录都有PHP运行身份的读写权限

方案3:修改PHP临时上传目录

在php.ini中修改upload_tmp_dir为网站目录树内的路径(比如C:\inetpub\wwwroot\your-site\temp-uploads),这样文件移动时处于同一目录树,权限会自动继承


内容的提问来源于stack exchange,提问作者Gubberrr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 07:43:09