$_files为空说明php未接收到文件,首要排查表单是否缺失enctype="multipart/form-data"、input name与$_files键名是否完全一致(大小写敏感)、是否使用post方法,以及ajax中是否误设content-type;还需检查nginx client_max_body_size、php upload_max_filesize与post_max_size配置是否匹配且单位正确,确认file_uploads=on并重启服务。

$_FILES 为空,基本可以断定 PHP 根本没收到文件——问题不在你的上传逻辑,而在请求被前端或服务器中途拦下了。
为什么 $_FILES 总是空数组?
这是最常被跳过的起点。空数组 ≠ 代码写错了,而是文件压根没进 PHP 的门。
-
enctype="multipart/form-data"缺失或拼写错误(比如写成enctype="multipart/form-data "多了个空格) -
的
name和 PHP 中读取的键名不一致,大小写敏感:前端是name="Avatar",PHP 却写$_FILES['avatar'] - 用 AJAX 提交时手动设置了
Content-Type,导致 boundary 被破坏,FormData失效 - Nginx 拦截了大请求:检查 error log 是否有
413 Request Entity Too Large,对应配置项是client_max_body_size - Apache 拦截:检查是否设置了过小的
LimitRequestBody
upload_max_filesize 改了但没生效?
PHP 8.5.5 对 ini 值解析更严格,单位写错就等于没设。
- 必须用大写单位:
128M✅,128m或128 MB❌(会被当 0 处理) -
post_max_size必须 ≥upload_max_filesize× 文件数 + 表单字段体积;上传 3 个 50MB 文件,post_max_size = 160M才安全 - 运行
php --ini确认真实加载的 php.ini 路径,再用var_dump(ini_get('upload_max_filesize'))验证返回值是不是字符串"128M" - 宝塔等面板用户注意:站点可能启用了独立 PHP 配置,全局改了没用,得进对应站点的 PHP 设置里单独调
move_uploaded_file() 失败但 error === 0?
临时文件已存好,说明上传成功;移动失败,问题全在目标路径侧。
-
move_uploaded_file()不会自动创建父目录,mkdir(dirname($target), 0755, true)得自己加 - Linux 下检查 Web 进程用户(如
www-data)对目标目录是否有写权限:ls -ld /var/www/html/uploads,再执行chown www-data:www-data /var/www/html/uploads - 容器环境确认挂载卷是
rw,Docker Compose 里漏掉read_only: false就会静默失败 - 跨文件系统移动(比如从
/tmp到挂载的 NFS 盘)不被支持,需改用copy() + unlink()
上传成功却找不到文件?
常见于 ThinkPHP 等框架,moveTo() 或 store() 行为受 disk 配置驱动,不是无脑保存。
-
'root' => 'public/uploads'是相对路径,实际根目录是public_path('uploads'),不是ROOT_PATH . 'public/uploads' - 切换到
qiniu或oss驱动后,moveTo()会直接失效——它只适用于local驱动 - 打印
$file->store('images')返回值,正常应是类似images/xxx.jpg的相对路径;返回false或抛异常,立刻查对应 disk 的root和url配置
$_FILES 为空时还在 debug 移动逻辑,或者 move_uploaded_file() 报错却没检查父目录是否存在。这些点不逐个排除,光看错误提示只会绕圈子。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











