如何批量校验CSV文件ID格式并修正代码,实现校验后插入MySQL
问题解答
1. 插入CSV到MySQL前检查所有无效ID的方法
要在插入前完成全量ID格式检查,需遵循先验证、后插入的流程:
- 打开CSV文件后逐行读取,提取每行的ID字段
- 用指定正则表达式验证ID格式,同时记录所有无效ID的行号和对应值
- 若存在无效项,直接输出包含错误位置的提示并终止操作;若所有ID合法,再执行数据插入
2. 修正后的PHP代码
原代码存在两个核心问题:一是遇到首个错误就终止,无法检查全部行;二是直接拼接SQL语句,存在严重SQL注入风险。以下是修复后的代码:
<?php if(isset($_POST['Submitbtn'])){ $uploaded_by = $_POST['uploaded_by']; // 允许的CSV MIME类型 $csvMimes = array('text/x-comma-separated-values', 'text/tab-separated-values', 'text/comma-separated-values', 'application/octet-stream', 'application/vnd.ms-excel', 'application/x-csv', 'text/x-csv', 'text/csv', 'application/csv', 'application/excel', 'application/vnd.msexcel', 'text/plain'); if(!empty($_FILES['file']['name']) && in_array($_FILES['file']['type'], $csvMimes)){ if(is_uploaded_file($_FILES['file']['tmp_name'])){ $csvFile = fopen($_FILES['file']['tmp_name'], 'r'); $validData = []; $errors = []; $lineNumber = 0; // 记录行号,方便定位错误 // 第一步:全量验证所有行的ID格式 while(($line = fgetcsv($csvFile)) !== FALSE){ $lineNumber++; // 跳过表头(如果CSV包含表头,不需要则注释此行) if($lineNumber === 1){ continue; } // 检查行数据完整性,避免索引越界 if(count($line) < 3){ $errors[] = "第{$lineNumber}行数据不完整,缺少必要字段"; continue; } $empno = trim($line[0]); $id = trim($line[1]); $code = trim($line[2]); // 验证ID格式 if(!preg_match("/^([0-9]{9}[xXvV]|[0-9]{12})$/", $id)){ $errors[] = "第{$lineNumber}行ID格式无效:{$id}"; } else { // 格式合法,存入待插入数组 $validData[] = [ 'empno' => $empno, 'id' => $id, 'code' => $code, 'uploaded_by' => $uploaded_by ]; } } fclose($csvFile); // 第二步:根据验证结果处理 if(!empty($errors)){ // 输出所有错误信息 echo "发现以下错误:<br>"; foreach($errors as $err){ echo "- {$err}<br>"; } } else { // 所有数据合法,执行插入(用预处理语句防SQL注入) if(!empty($validData)){ $stmt = mysqli_prepare($conn, "INSERT INTO company (empno, id, code, uploaded_by) VALUES (?, ?, ?, ?)"); mysqli_stmt_bind_param($stmt, "ssss", $empno, $id, $code, $uploaded_by); $insertSuccess = true; foreach($validData as $data){ $empno = $data['empno']; $id = $data['id']; $code = $data['code']; $uploaded_by = $data['uploaded_by']; if(!mysqli_stmt_execute($stmt)){ $insertSuccess = false; break; } } mysqli_stmt_close($stmt); if($insertSuccess){ echo "数据导入成功!共插入" . count($validData) . "条记录"; } else { echo "插入数据时出错,请重试"; } } else { echo "没有可导入的有效数据"; } } } else { echo "文件上传失败,请重试"; } } else { echo "请上传有效的CSV文件"; } } ?>
关键修复点说明
- 全量验证:遍历完整个CSV文件后再处理,用户能看到所有无效行的具体位置,不会中途终止
- SQL注入防护:使用mysqli预处理语句,避免直接拼接变量导致的注入风险
- 边界处理:增加行数据完整性检查,避免因字段缺失引发的索引错误;可按需启用表头跳过逻辑
- 错误反馈:输出详细的错误信息,方便用户定位并修正CSV问题
内容的提问来源于stack exchange,提问作者pawani shashi
相关产品推荐
相关产品推荐

