PHP多图上传时$_FILES是按字段名分层的二维结构,需先检查$_FILES'images'是否为数组,再遍历索引$i获取各文件信息;move_uploaded_file()仅支持单文件,须逐个校验MIME、大小、错误码并生成唯一文件名。

PHP 多图上传时 $_FILES 结构容易看错
PHP 接收多图上传时,$_FILES 不是扁平数组,而是按字段名分层嵌套的二维结构。如果前端用 <input type="file" name="images[]" multiple>,实际收到的是:$_FILES['images']['name'][0]、$_FILES['images']['tmp_name'][0] 等,而不是 $_FILES['images'][0]['name']。
常见错误是直接遍历 $_FILES['images'],结果报 Warning: Invalid argument supplied for foreach() 或只取到第一个文件。
- 务必先检查
is_array($_FILES['images']['name']),再用count($_FILES['images']['name'])获取数量 - 遍历时统一索引:对每个
$i,取$_FILES['images']['name'][$i]、$_FILES['images']['tmp_name'][$i]、$_FILES['images']['error'][$i] - 跳过
$_FILES['images']['error'][$i] === UPLOAD_ERR_NO_FILE的空项(比如用户选了 3 个但删掉一个)
验证和移动文件必须逐个处理,不能批量调用 move_uploaded_file()
move_uploaded_file() 只接受单个 $from 和 $to 参数,无法传入数组。强行用 move_uploaded_file($_FILES['images']['tmp_name'], $dest) 会警告“Expected string, array given”。
更关键的是,每个文件都要独立校验:类型、大小、错误码、扩展名。漏掉任意一项都可能引发安全或稳定性问题。
- 在循环内对每个文件单独检查
$_FILES['images']['error'][$i]——UPLOAD_ERR_OK才继续 - 用
finfo_open(FILEINFO_MIME_TYPE)检查真实 MIME 类型,别只信$_FILES['images']['type'][$i](浏览器可伪造) - 生成唯一文件名(如
uniqid() . '.' . pathinfo($originalName, PATHINFO_EXTENSION)),避免覆盖或冲突
前端 <form></form> 必须带 enctype="multipart/form-data" 且字段名含 []
缺 enctype 会导致 $_FILES 为空;字段名没写方括号,PHP 就当单文件处理,即使加了 multiple 属性也只会收到最后一个文件。
立即学习“PHP免费学习笔记(深入)”;
典型正确写法:
<form method="post" enctype="multipart/form-data"> <input type="file" name="photos[]" multiple accept="image/*"> <button type="submit">上传</button> </form>
-
accept="image/*"是前端提示,不影响后端逻辑,不能替代 MIME 校验 - 如果用 JS 动态添加多个
<input type="file">,字段名要保持一致(如全为photos[]),否则 PHP 会拆成多个键 - 大文件需同步调整
php.ini:增大upload_max_filesize、post_max_size、max_execution_time
上传失败时,$_FILES 的 error 值比报错信息更可靠
PHP 不会自动抛异常,所有上传问题都收敛到 $_FILES['xxx']['error'][$i]。靠 try/catch 捕获不到上传失败,打印 $_FILES 也常显示空数组或部分字段缺失。
真正有用的只有那个整数错误码。比如 UPLOAD_ERR_INI_SIZE(1)表示超 upload_max_filesize,UPLOAD_ERR_FORM_SIZE(2)是超表单限制,UPLOAD_ERR_NO_FILE(4)才是真没选文件。
- 不要用
empty($_FILES)判断是否上传 —— 即使用户没选文件,$_FILES仍存在,只是error为 4 - 调试时优先输出
var_dump($_FILES['photos']['error'] ?? 'no photos key'),比看整个$_FILES更快定位 - 注意:Nginx 默认有
client_max_body_size限制,和 PHP 设置不一致时,请求可能根本到不了 PHP 层
多图上传真正的复杂点不在循环本身,而在每张图的独立校验路径、错误归因和并发安全性(比如同时上传同名临时文件)。哪怕只漏掉一次 finfo 检查或没过滤掉 .phar 扩展名,就可能变成远程代码执行入口。



















