PHP/CodeIgniter解析嵌套JSON提取字段动态入库方案求教
PHP实现JSON数据解析入库方案
整体思路
- 第一步:将API返回的JSON字符串解析为PHP关联数组,忽略无需处理的
Attachements和Total字段 - 第二步:遍历外层
Values数组,每个子项对应一条数据库记录 - 第三步:单条记录内遍历
AttributeValues节点,将Code字段作为数据表字段名,Values数组的首个元素作为字段值,拼接为插入用的关联数组 - 第四步:做数据类型转换、字段白名单过滤后,执行数据库插入操作
原生PHP实现(PDO版本)
<?php // 1. 接收/读取API返回的JSON字符串 $jsonStr = '你的API返回的JSON内容'; // 2. 解析JSON为关联数组 $data = json_decode($jsonStr, true); if (json_last_error() !== JSON_ERROR_NONE) { die('JSON解析错误: ' . json_last_error_msg()); } // 3. 定义数据表允许插入的字段白名单(和实际表结构对应即可) $allowFields = ['ID', 'TrackingNumber', 'CustomerFull', 'ServiceCode', 'RequestDate']; // 4. 初始化PDO连接(替换为你自己的数据库配置) $pdo = new PDO('mysql:host=127.0.0.1;dbname=你的库名;charset=utf8mb4', '用户名', '密码'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); // 5. 遍历处理每条记录 foreach ($data['Values'] as $item) { $insertData = []; foreach ($item['AttributeValues'] as $attr) { $code = $attr['Code']; // 过滤不在白名单的字段 if (!in_array($code, $allowFields)) continue; // 取Values数组第一个值,若业务允许多值可转JSON字符串存储 $value = $attr['Values'][0] ?? null; // 根据DataType字段做对应数据类型转换 if ($attr['DataType'] == 'Datetime') { $value = date('Y-m-d H:i:s', strtotime($value)); } elseif ($attr['DataType'] == 'Number') { $value = intval($value); } $insertData[$code] = $value; } // 拼接预处理SQL $fields = implode(',', array_keys($insertData)); $placeholders = ':' . implode(',:', array_keys($insertData)); $sql = "INSERT INTO 你的表名 ($fields) VALUES ($placeholders)"; // 执行插入 $stmt = $pdo->prepare($sql); $stmt->execute($insertData); } echo '插入完成'; ?>
CodeIgniter 实现(兼容3.x/4.x版本)
3.x版本代码示例
<?php // 1. 解析JSON $jsonStr = '你的API返回的JSON内容'; $data = json_decode($jsonStr, true); if (json_last_error() !== JSON_ERROR_NONE) { show_error('JSON解析失败'); } $allowFields = ['ID', 'TrackingNumber', 'CustomerFull', 'ServiceCode', 'RequestDate']; $insertBatch = []; // 2. 处理批量插入数据 foreach ($data['Values'] as $item) { $row = []; foreach ($item['AttributeValues'] as $attr) { $code = $attr['Code']; if (!in_array($code, $allowFields)) continue; $value = $attr['Values'][0] ?? null; if ($attr['DataType'] == 'Datetime') { $value = date('Y-m-d H:i:s', strtotime($value)); } elseif ($attr['DataType'] == 'Number') { $value = intval($value); } $row[$code] = $value; } $insertBatch[] = $row; } // 3. 调用CI查询构造器批量插入(自动防SQL注入) $this->load->database(); $this->db->insert_batch('你的表名', $insertBatch); echo '成功插入' . $this->db->affected_rows() . '条数据'; ?>
4.x版本代码差异
仅数据库调用部分修改为:
$db = \Config\Database::connect(); $builder = $db->table('你的表名'); $builder->insertBatch($insertBatch); echo '成功插入' . $db->affectedRows() . '条数据';
注意事项
- 字段白名单必须提前配置,避免部分记录多出的字段导致插入SQL报错
- 若
Values字段存在多个值的情况,可根据业务需求转为JSON字符串或逗号分隔字符串存储 - 日期格式转换需注意时区问题,避免写入的时间和实际时间偏差
- 数据量较大时建议分批插入,避免单次SQL过长导致执行失败
内容的提问来源于stack exchange,提问作者Girmangus Hailu
相关产品推荐
相关产品推荐

