PHP解析XML商品Feed遍历PARAM多维数组取值异常问题
问题根因
你遇到的是SimpleXML转数组的经典兼容问题:
- 当商品下
<PARAM>节点数量≥2时,json_decode解析后会生成索引二维数组,每个子项对应一个参数的PARAM_NAME和VAL - 当商品下
<PARAM>节点数量=1时,json_decode解析后会直接生成一维关联数组,结构为['PARAM_NAME'=>'xxx', 'VAL'=>'yyy'],不会套一层索引数组
你直接遍历$products['PARAM']时,单参数场景下会把PARAM_NAME、VAL两个字段当成独立遍历项,直接输出拼接字符串,和多参数场景的遍历逻辑不兼容。
修复方案
两种实现方式,都可以兼容单参数、多参数两种场景:
方案1:兼容你现有转数组的逻辑
在遍历PARAM前做一次结构归一化,把单参数的一维数组转成和多参数一致的二维索引数组,再统一遍历:
$xml = simplexml_load_file($input) or die ("ERROR : Cannot create object"); $json = json_encode($xml); $array = json_decode($json,TRUE); foreach($array['SHOPITEM'] as $products) { if(!isset($products['PARAM'])) { continue; } // 核心:统一PARAM数据结构 $paramList = $products['PARAM']; // 检测到是单参数结构(存在PARAM_NAME键),套一层数组转成列表结构 if(isset($paramList['PARAM_NAME'])) { $paramList = [$paramList]; } // 后续遍历逻辑完全统一 $productParams = []; foreach ($paramList as $param){ // 可以直接提取为变量,也可以存为键值对 $paramName = $param['PARAM_NAME']; $paramVal = $param['VAL']; $productParams[$paramName] = $paramVal; } // $productParams 即为当前商品所有参数的键值对集合 print_r($productParams); }
方案2:直接用SimpleXML原生遍历(更推荐,从根源避免结构问题)
不用走json转数组的逻辑,SimpleXML本身对同名多节点的遍历做了原生兼容,不管PARAM是1个还是多个,遍历逻辑完全一致:
$xml = simplexml_load_file($input) or die ("ERROR : Cannot create object"); foreach($xml->SHOPITEM as $product) { $productParams = []; // 直接遍历所有PARAM子节点,自动适配节点数量 foreach($product->PARAM as $param) { // 强转string拿到节点实际值,避免拿到SimpleXML对象 $paramName = (string)$param->PARAM_NAME; $paramVal = (string)$param->VAL; $productParams[$paramName] = $paramVal; } print_r($productParams); }
注意事项
- 不要用
count()判断PARAM是单条还是多条:单条PARAM的一维数组count结果是2(包含PARAM_NAME、VAL两个元素),会导致判断逻辑失效,直接判断是否存在PARAM_NAME键的准确率100% - 用SimpleXML读取节点值时必须强转
(string),否则拿到的是SimpleElement对象,后续存库、输出可能出现隐式类型错误
内容的提问来源于stack exchange,提问作者Pe Tr
相关产品推荐
相关产品推荐

