必须显式配置upload_tmp_dir才生效,因其默认被注释而退至系统临时目录(如C:\Windows\Temp),但Apache以NT AUTHORITY\SYSTEM运行时无写权,导致$_FILES'file'为空或move_uploaded_file()静默失败;ini_set无效,须编辑php.ini取消注释并设绝对路径,再用icacls授SYSTEM完全控制权,最后完整Stop/Start Apache服务。

upload_tmp_dir 在 XAMPP 中必须显式配置才生效
php.ini 里 upload_tmp_dir 默认是被注释掉的,此时 PHP 会退回到系统默认临时目录(Windows 下常为 C:\Windows\Temp),但该路径往往被 Apache 的运行账户(NT AUTHORITY\SYSTEM)拒绝写入——所以即使上传表单正常提交,$_FILES['file']['tmp_name'] 也可能为空,或 move_uploaded_file() 静默失败。
注意:ini_set('upload_tmp_dir', ...) 在任何场景下都无效,这是 PHP 内核硬性限制,别白费力气试。
- 先确认当前生效的 php.ini 路径:运行
php --ini或创建一个phpinfo()页面查看 “Loaded Configuration File” - 编辑该文件,取消注释并设置绝对路径,例如:
upload_tmp_dir = "C:\xampp\tmp"(Windows)或upload_tmp_dir = "/opt/lampp/temp"(Linux/macOS 类 XAMPP) - 路径必须是绝对路径,不能用
./tmp或../temp这类相对写法
Windows 下授予权限必须用 icacls 针对 SYSTEM 主体
XAMPP 的 Apache 在 Windows 上默认以 LocalSystem 身份运行,它对应的安全主体是 NT AUTHORITY\SYSTEM,不是你当前登录的用户,也不是 Administrators 组。图形界面右键设权限经常漏掉继承标记,导致重启后仍报 Failed to move uploaded file 或 Permission denied。
- 以管理员身份打开命令提示符
- 执行:
mkdir C:\xampp\tmp(如果目录不存在) - 再执行:
icacls "C:\xampp\tmp" /grant "NT AUTHORITY\SYSTEM:(OI)(CI)F" /T -
(OI)表示对象继承,(CI)表示容器继承,F是完全控制,/T确保递归应用到子目录和文件 - 改完必须用 XAMPP Control Panel 完整 Stop → Start Apache,仅重载配置不生效
Linux/macOS 类 XAMPP 环境要匹配 Apache 进程用户
Linux 版 XAMPP 已停止维护,但如果你用的是 Bitnami、旧版 LAMPP 或自建类 XAMPP 环境,Apache 进程通常以 daemon、www-data 或 apache 用户运行。权限错配时错误信息更隐蔽,比如只报 Warning: Failed to write session data,其实根源和上传失败一样——upload_tmp_dir 目录不可写。
立即学习“PHP免费学习笔记(深入)”;
- 查真实运行用户:
ps aux | grep -E '(apache|httpd)' | grep -v grep,看 USER 列 - 确保目录存在且归属正确:
sudo mkdir -p /opt/lampp/temp && sudo chown daemon:daemon /opt/lampp/temp - 权限必须是
700或750,严禁777—— PHP 官方明确要求该目录不能被组或其他用户写入,否则直接拒绝上传 - 若启用了 SELinux(如 CentOS/RHEL),还需补上下文:
sudo semanage fcontext -a -t httpd_tmp_t "/opt/lampp/temp(/.*)?" && sudo restorecon -Rv /opt/lampp/temp
验证 upload_tmp_dir 是否真正生效
改完配置、赋权、重启服务后,别急着传文件。很多问题卡在“以为改好了”,实际 upload_tmp_dir 没加载成功,或者被 open_basedir 限制了访问。
- 写个测试脚本:
<?php echo ini_get('upload_tmp_dir'); ?>,输出应为非空字符串且与你设置的路径一致 - 检查是否被 open_basedir 限制:
php -i | grep open_basedir,如果返回值不是no value,确认你设的upload_tmp_dir路径在允许范围内 - 上传一个最小文件(如 1KB txt),然后立刻打印
$_FILES全量内容,观察tmp_name是否指向你指定的目录 - 如果仍失败,翻
error_log(XAMPP 日志在C:\xampp\apache\logs\error.log或/opt/lampp/logs/error_log),搜索upload或tmp关键字
最容易被忽略的是:路径存在、权限看着对、配置也写了,但没重启 Apache(不是 reload,是 stop+start),或者 SELinux/AppArmor 等安全模块悄悄拦住了写操作。



















