CodeIgniter中CSV导入数据库时数组字段提取报错求助
问题分析与解决方案
咱们先拆解你遇到的核心问题,再一步步给出修复方案:
1. 数组层级错误导致变量未定义
你的csv_process()函数已经返回了一个二维数组(每个元素是包含name和email的关联数组),但在action()里你写了:
$toWrite[] = $this->csv_process();
这相当于把整个返回的数组再套进一个新数组里,变成了三维数组。后续foreach遍历的时候,$arr其实是原来的整个二维数组,而非单个用户数据项,自然提取不到目标字段。
2. list()无法处理关联数组
list()只能用于索引数组(按顺序取值),但你的csv_process()返回的是关联数组(键是name和email),所以list($name, $email) = $arr;完全不生效,这也是你拿不到变量的直接原因。
修正后的代码步骤
第一步:修复action()的数组赋值逻辑
直接接收csv_process()的返回值,不要多套一层数组:
function action(){ // 直接获取csv_process返回的二维数组,去掉多余的[] $toWrite = $this->csv_process(); // 先判断数组是否有效,避免空数组遍历报错 if (!empty($toWrite)) { foreach ($toWrite as $user) { // 直接通过关联数组的键提取值 $name = $user['name']; $email = $user['email']; // 后续逻辑... } } }
第二步:补全csv_process()的变量初始化
如果文件不满足条件(比如扩展名不对、文件大小为0),$toWrite变量会未定义,返回时会报错。所以要在函数开头先初始化这个变量:
public function csv_process() { // 先初始化数组,避免异常情况无返回值 $toWrite = array(); /* 打开CSV文件的变量 */ if (!in_array($extension, $allowed_ext)) { $this->session->set_flashdata("message", "Sorry, CSV file only."); } else { if ($filesize > 0) { // 原有的文件读取逻辑... } } return $toWrite; }
第三步:替换不安全的SQL拼接(重要!)
你现在直接把变量拼进SQL里,存在严重的SQL注入风险,建议用CodeIgniter的参数绑定功能:
// 替换查询语句 $query = $this->db->query( "SELECT * FROM import WHERE name = ? AND email = ?", array($name, $email) ); // 替换插入语句 $this->db->query( "INSERT INTO import(name, email, created_date) VALUES(?, ?, ?)", array($name, $email, date("Y-m-d H:i:s")) );
另外,日期格式建议用H:i:s(24小时制),避免和h(12小时制)混淆。
额外优化建议
- 在
csv_process()里,当列数不符合要求时,建议直接终止循环或标记错误,避免继续读取无效数据; - 在
action()里,redirect语句放在循环内会导致只处理第一条有效数据就跳转,建议把成功提示放在循环结束后,或者统计成功插入的数量再统一提示。
内容的提问来源于stack exchange,提问作者Levera_Lily
相关产品推荐
相关产品推荐

