通过动态输入字段将多文件及类型插入MySQL,解决仅首条插入问题
多文件上传入库问题修复方案
1. 优先检查表单基础配置
你的HTML表单必须加上enctype="multipart/form-data"属性,这是多文件上传的必填配置,缺失该属性会导致后端只能接收到第一个文件,是该问题最常见的诱因。
2. 修复PHP端逻辑错误
现有PHP代码存在多处逻辑漏洞,是插入失败的核心原因:
- 无论文件格式验证是否通过,都会执行插入操作,验证不通过时
$cert1未赋值,要么插入空数据,要么复用上次循环的旧值导致插入异常 - 未判断文件是否上传成功,直接读取临时文件内容
end(explode())写法在PHP7.1+版本会抛出严格语法错误- 未做变量重置,存在循环内变量污染问题
修复后的代码参考:
if($q >= 0){ // 预准备SQL放到循环外,大幅提升执行性能 $sql3="INSERT INTO shorttest (cert,dtype) VALUES (:cert,:dtype)"; $query = $dbh->prepare($sql3); $fileType = array("png", "jpg", "jpeg", "pdf"); $error = ""; for($i=0; $i<=$q; $i++){ // 先判断当前文件是否成功上传,跳过空字段 if(!isset($_FILES['cert']['error'][$i]) || $_FILES['cert']['error'][$i] != UPLOAD_ERR_OK){ continue; } $certcheck = true; // 用pathinfo正确获取文件扩展名 $upload = pathinfo($_FILES['cert']['name'][$i], PATHINFO_EXTENSION); $imageType = $_FILES['cert']['type'][$i]; $cert1 = null; if (in_array(strtolower($upload), $fileType)) { $cert1 = file_get_contents($_FILES['cert']['tmp_name'][$i]); } else { $error = "存在不符合格式的文件,仅支持png、jpg、jpeg、pdf格式,请重新上传"; $certcheck = false; $_SESSION['error'] = $error; // 验证失败直接终止流程,避免部分插入的脏数据 break; } // 仅验证通过的文件才执行插入 if($certcheck && $cert1 !== null){ $query->bindParam(':cert', $cert1, PDO::PARAM_STR); $query->bindParam(':dtype', $imageType, PDO::PARAM_STR); $query->execute(); } } if(empty($error)){ $msg = "您的申请已提交成功!"; } }
3. 修复JS端逻辑漏洞
现有代码仅实现了新增字段逻辑,未同步处理删除字段时的计数逻辑,如果用户新增字段后又删除,q值会比实际存在的字段数大,循环时会遍历到不存在的空字段导致插入失败。补充删除事件绑定:
var q = 0; // 新增动态元素的删除事件绑定 $('#tbl_qualification').on('click', '.remove', function() { $(this).closest('tr').remove(); q--; document.getElementById("q").value = q; }); function qualification() { q++; var copyContent= "<tr><td><input class='tableBody' type='file' id='cert"+q+"' name='cert[]'></td>"; copyContent += "<td><a href='javascript:void(0);' class='remove' style='cursor:pointer'><i class='material-icons' title='Delete item'>remove_circle_outline</i></a></td></tr>"; $('#tbl_qualification').append(copyContent); document.getElementById("q").value = q; }
4. 可选安全优化
可以不依赖前端传的q值,PHP端直接读取上传文件的实际数量,避免前端参数被篡改导致的异常,安全性更高:
// 替换原有$q的判断逻辑,直接取实际上传的文件数量 $fileCount = count($_FILES['cert']['name']); for($i=0; $i<$fileCount; $i++){ // 后续循环逻辑和上述修复后的代码一致 }
内容的提问来源于stack exchange,提问作者gammer
相关产品推荐
相关产品推荐

