如何通过PHP将含空行的嵌套JSON数据存入Oracle数据库?
问题解决:过滤JSON无效空行并批量插入Oracle数据库
问题背景
从外部系统获取的嵌套JSON数据包含无效的\r\n空行条目,需要提取其中4条有效数据存入Oracle数据库,但现有PHP代码仅能处理部分数据,无法完整插入所有有效记录。
JSON示例
{ "ErrorCode": "00", "ErrorMessage": "", "ServiceList": { "ServiceDetail": [ { "Service_name": [ "LTE_DATA_PRI_1", "LTE_ONM_PRI_2" ], "AVLAN": [ "LTE_DATA_PRI_SITE_1", "LTE_DATA_PRI_SITE_2" ], "IpAddress": [ "192.168.1/20", "192.168.2/20" ], "AggPort": [ "GigabitEthernet 1/1/10.1000", "GigabitEthernet 1/1/10.1001" ] }, "\r\n", "\r\n", { "Service_name": [ "LTE_DATA_SEC_1", "LTE_ONM_SEC_2" ], "AVLAN": [ "LTE_DATA_SEC_SITE_1", "LTE_DATA_SEC_SITE_2" ], "IpAddress": [ "192.168.3/20", "192.168.4/20" ], "AggPort": [ "GigabitEthernet 1/1/10.1003", "GigabitEthernet 1/1/10.1004" ] }, "\r\n", "\r\n" ] } }
现有PHP代码
$i = 0; $x = 0; $arrayLength = count($array['ServiceList']['ServiceDetail']); while ($x < $arrayLength) { $arrayLength2 = count($array['ServiceList']['ServiceDetail'][$x]['AVLAN']); while ($i < $arrayLength2) { $AVLAN1 = $array['ServiceList']['ServiceDetail'][$x]['AVLAN']; if ( $AVLAN1 !== null){ $p_avlan = $array['ServiceList']['ServiceDetail'][$x]['AVLAN'][$i]; $p_agg_port = $array['ServiceList']['ServiceDetail'][$x]['AggPort'][$i]; $p_ip_address = $array['ServiceList']['ServiceDetail'][$x]['IpAddress'][$i]; $p_service_name = $array['ServiceList']['ServiceDetail'][$x]['Service_name'][$i]; // sql procedure here // $i++; } } // while 2 $x++; } // while 1
解决方案
核心问题分析
- 未过滤
ServiceDetail中的\r\n空行条目,导致循环时会尝试处理非对象类型的元素,引发错误或跳过有效数据。 - 内层循环变量
$i在外部初始化,处理完第一个有效对象后$i已经是2,后续遍历第二个对象时内层循环直接不执行。
修改后的代码
// 先过滤ServiceDetail中的无效空行,只保留对象类型的条目 $validServiceDetails = array_filter($array['ServiceList']['ServiceDetail'], function($item) { return is_array($item); // 排除字符串类型的\r\n }); // 遍历所有有效服务详情 foreach ($validServiceDetails as $detail) { // 每次处理新的详情时,重置内层循环索引 $i = 0; $detailLength = count($detail['AVLAN']); while ($i < $detailLength) { // 提取当前条目的所有字段 $p_avlan = $detail['AVLAN'][$i]; $p_agg_port = $detail['AggPort'][$i]; $p_ip_address = $detail['IpAddress'][$i]; $p_service_name = $detail['Service_name'][$i]; // 执行Oracle插入逻辑(此处替换为你的SQL存储过程或插入语句) // 示例:oci_execute($stmt); 建议使用绑定参数防止SQL注入 $i++; } }
代码说明
- 使用
array_filter过滤掉ServiceDetail中的字符串空行,只保留包含有效字段的数组对象。 - 把内层循环的索引
$i放到外层循环内部初始化,确保每个有效对象的子条目都能从0开始遍历。 - 改用
foreach遍历过滤后的有效数据,代码更简洁易读,避免手动维护索引变量。
内容的提问来源于stack exchange,提问作者Asrol Hassan
相关产品推荐
相关产品推荐

