php上传文件丢失主因是upload_tmp_dir目录不存在、未生效或权限不足,需通过phpinfo()确认真实路径,用icacls强制赋权并确保open_basedir包含该路径,且is_writable()返回true。

phpEnv 下 PHP 上传文件丢失,大概率不是代码问题,而是 upload_tmp_dir 目录不存在、路径没生效,或 PHP 进程(通常是 www 或 apache)根本没权限往里写。
确认 phpEnv 实际使用的 upload_tmp_dir 路径
phpEnv 是 Windows 下的便携式 PHP 环境,不走系统服务安装流程,所以它不会自动继承 Apache 或 Nginx 的用户上下文——它的 PHP-CGI 或 PHP-FPM 进程默认以当前登录用户身份运行,但临时目录权限仍可能被 UAC 或 ACL 拦截。
必须验证真实生效路径,不能只看 php.ini 里写了什么:
- 在 phpEnv 根目录下新建
info.php,内容为<?php phpinfo(); ?>,用浏览器访问,搜索upload_tmp_dir行,看“Local Value”列的值 - 若显示
no value,说明配置未生效,或被open_basedir限制了路径范围 - 若显示一个路径(如
C:\phpenv\tmp),立刻用资源管理器打开该路径,确认目录存在且不是只读
Windows 下给 phpEnv 的 upload_tmp_dir 正确赋权(关键步骤)
图形界面右键 → “属性” → “安全” 常常漏掉继承控制和 SYSTEM 权限,导致看似给了权限,实际仍失败。必须用 icacls 强制设置:
- 以管理员身份打开命令提示符(非 PowerShell)
- 执行:
icacls "C:\phpenv\tmp" /grant "BUILTIN\Users:(OI)(CI)F" /T(若 phpEnv 启动时用的是当前用户) - 或更稳妥地加 SYSTEM:
icacls "C:\phpenv\tmp" /grant "NT AUTHORITY\SYSTEM:(OI)(CI)F" /T - 确保目录本身无“只读”属性:在资源管理器中右键 → 属性 → 取消勾选“只读” → 应用于该文件夹、子文件夹和文件
注意:(OI)(对象继承)和 (CI)(容器继承)缺一不可,否则新建的临时文件会沿用父目录旧权限,导致 move_uploaded_file() 失败。
修改 php.ini 后必须重启 phpEnv 的 Web 服务进程
phpEnv 自带的 Apache/Nginx 是以 Windows 服务或控制台进程方式运行的,改完 php.ini 后:
- 不要只点“重载配置”,必须完全停止再启动 Apache/Nginx 进程
- 在 phpEnv 主界面,点击对应服务器右侧的 Stop,等状态变灰后再点 Start
- 如果用的是 PHP-CGI 模式(如配合 Nginx),还要确认
php-cgi.exe进程已退出(任务管理器中查php-cgi) - 验证是否加载新配置:再次访问
info.php,确认upload_tmp_dir的Local Value和Master Value一致,且路径可写
容易被忽略的干扰项:open_basedir 和 session.save_path
upload_tmp_dir 不是孤立存在的——如果 open_basedir 没包含该路径,PHP 会直接拒绝写入;如果 session.save_path 也指向同一父目录但权限不对,会导致整个请求生命周期中断(表现为上传后 $_FILES 为空,但无报错)。
- 检查 php.ini 中
open_basedir是否包含你设的upload_tmp_dir路径,例如:open_basedir = C:\phpenv\www;C:\phpenv\tmp - 检查
session.save_path是否也指向一个可写的目录,否则 session 初始化失败可能让后续文件上传逻辑跳过或静默终止 - 用 PHP 函数快速验证:
var_dump(is_writable('C:\phpenv\tmp'));—— 必须返回true才算真正可写
临时目录权限问题最麻烦的地方在于:错误不总直接暴露。$_FILES['xxx']['error'] === 6(找不到临时文件夹)还算友好,更多时候是 move_uploaded_file() 返回 false 却不告诉你为什么——得靠 is_writable() 和 phpinfo() 交叉验证,而不是凭感觉改路径或 chmod。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











