MySQL设置唯一列后CodeIgniter导入Excel时flashdata提示异常如何解决
问题原因
- 逻辑位置错误:你将插入结果判断和
redirect跳转逻辑放在了工作表遍历循环内部,代码处理完第一个工作表后就会直接跳转,后续工作表永远不会被执行;如果第一个工作表没有有效可插入数据,插入操作直接返回false,就会始终触发错误提示。 - 数组未初始化:
$data数组没有提前初始化,当Excel中没有符合!empty($sendername)条件的行时,$data属于未定义变量,传入模型执行插入会直接返回false。 - 唯一约束导致批量插入失败:默认CodeIgniter的
insert_batch()批量插入方法遇到唯一键冲突时,整个插入操作会全部失败,不会只跳过冲突行,就算你肉眼看部分数据应该要插入,只要有一条重复,全量插入都会失败返回false。 - 模型返回值逻辑错误:大部分开发者写模型插入方法时会直接返回
$this->db->insert_batch()的执行结果,但是CodeIgniter的insert_batch()执行成功后返回的是第一个插入行的自增ID,不是布尔值true;如果插入的第一条数据ID为0或者插入行数为0时,会被判定为false触发错误提示。
修复方案
第一步:修改控制器逻辑
调整循环结构,初始化数组,所有数据处理完成后再统一判断跳转:
function import_domestic_excel_data(){ if(isset($_FILES["file"]["name"])){ $path = $_FILES["file"]["tmp_name"]; $object = PHPExcel_IOFactory::load($path); $total_insert = 0; // 统计总插入行数 foreach($object->getWorksheetIterator() as $worksheet){ $highestRow = $worksheet->getHighestRow(); $highestColumn = $worksheet->getHighestColumn(); $data = []; // 每个工作表单独初始化数据数组 for($row=2; $row<=$highestRow; $row++){ $sendername = $worksheet->getCellByColumnAndRow(0, $row)->getValue(); $senderreference = $worksheet->getCellByColumnAndRow(1, $row)->getValue(); if(!empty($sendername)){ $data[] = [ 'sendername' => $sendername, 'senderreference' => $senderreference, ]; } } // 存在有效数据再执行插入 if(!empty($data)){ $total_insert += $this->excel_import_model->insert_excel($data); } } // 所有工作表处理完成后统一返回提示 if($total_insert > 0){ $this->session->set_flashdata("Success","成功新增 {$total_insert} 条数据!"); }else{ $this->session->set_flashdata("Error","无新增数据,可能存在重复记录或导入文件无有效内容"); } redirect('listconsignment' , 'refresh'); } }
第二步:修改模型插入逻辑
开启INSERT IGNORE跳过唯一键冲突的行,返回实际插入的行数:
function insert_excel($data){ // 临时关闭数据库调试模式,避免冲突时直接抛出错误 $this->db->db_debug = false; // 批量插入,自动跳过唯一键冲突的记录,替换为你的实际表名 $this->db->insert_batch('你的业务表名', $data); // 获取实际影响的行数(即成功插入的行数) $affected = $this->db->affected_rows(); // 恢复数据库调试模式 $this->db->db_debug = true; return $affected; }
内容的提问来源于stack exchange,提问作者Zubi Da
相关产品推荐
相关产品推荐

