XAMPP for Windows 中 upload_tmp_dir 默认路径 C:\xampp\tmp 权限不足,因 Apache 以 NT AUTHORITY\SYSTEM 运行,需用 icacls 命令精确授予 (OI)(CI)F 继承式完全控制权限,否则 PHP 静默回退至系统临时目录导致上传失败。

Windows 下 XAMPP 的 upload_tmp_dir 默认值(C:\xampp\tmp)几乎必然权限不足,改路径不授予权限等于白改。
为什么改了 php.ini 还是上传失败?
根本不是路径写错或没重启服务的问题,而是 Apache 以 NT AUTHORITY\SYSTEM 身份运行,对 C:\xampp\tmp 默认没有写权限。即使你手动创建了目录、甚至用资源管理器右键“赋予完全控制”,也大概率漏掉继承权限和系统级 ACL 控制项。
- PHP 启动时检查该目录可写性,失败则静默 fallback 到系统默认(如
C:\Windows\Temp),但那个路径同样可能被策略锁定 -
move_uploaded_file()报错Unable to move uploaded file或返回false且$_FILES['x']['error'] === 0,基本可锁定是upload_tmp_dir权限问题 - 别信“改完 php.ini 就行”——XAMPP 控制面板里点“重启 Apache”不会触发权限重载,必须手动跑命令
Windows 下正确授权步骤(管理员 CMD)
必须用 icacls 命令精确设置继承式完全控制,图形界面做不到。
- 先确认目录存在:
mkdir C:\xampp\tmp - 执行授权命令(一行,注意引号和括号):
icacls "C:\xampp\tmp" /grant "NT AUTHORITY\SYSTEM:(OI)(CI)F" /T -
(OI)表示对象继承(子文件)、(CI)表示容器继承(子目录)、F是完全控制、/T递归应用 - 验证是否生效:在 PHP 脚本里打印
is_writable('C:\xampp\tmp'),应返回true
Linux/macOS 下 XAMPP(或类似 LAMP 包)权限要点
Apache 或 PHP-FPM 进程用户(通常是 daemon 或 www-data)必须是目录的 owner,且不能开放组/其他写权限——PHP 官方强制校验这一点。
立即学习“PHP免费学习笔记(深入)”;
- 创建目录:
sudo mkdir -p /opt/lampp/temp - 赋权(关键!不能
777):sudo chown daemon:daemon /opt/lampp/temp && sudo chmod 700 /opt/lampp/temp - 修改
/opt/lampp/etc/php.ini中的upload_tmp_dir = /opt/lampp/temp(取消注释) - 重启服务:
sudo /opt/lampp/lampp restart,不是只 restart apache - 验证:
php -i | grep upload_tmp_dir看路径是否匹配,再ls -ld /opt/lampp/temp确认 owner 和权限
容易被忽略的硬性限制
即使路径、权限、重启全对,仍可能失败——这些限制 PHP 不报明确错误,只让 move_uploaded_file() 静默失败。
-
upload_tmp_dir必须是**绝对路径**,不能含环境变量或波浪号(~) - 不能是符号链接(symlink),某些 PHP 版本 + open_basedir 启用时直接拒绝
- 路径不能跨挂载点(比如
/tmp在独立分区且挂载了noexec) - SELinux/AppArmor 启用时,需额外打标签(Linux);macOS 上注意 SIP 对
/tmp子目录的限制 -
ini_set('upload_tmp_dir', ...)永远无效,这是 PHP 内核级禁用



















