PHP array_key_exists条件不生效:XML转JSON后错误分支未触发
问题根因定位
你的判断逻辑完全匹配不上实际解析后的数组结构,核心问题有两个:
第一,判断的键名完全错误
你代码里判断的是isset($finalJson['ErrorResponse']),但根据你自己调试打印的结果,不管成功还是失败场景,解析后的数组顶级层根本不存在ErrorResponse这个键:
- 错误场景下,数组顶级键只有
Error和RequestID - 成功场景下,数组顶级键只有
GetTransportContentResult和ResponseMetadata
这是SimpleXML搭配json_encode的固有特性:序列化的时候会直接扁平化XML根节点——也就是XML最外层的根标签名(比如错误响应的<ErrorResponse>、成功响应的<GetTransportContentResponse>)不会作为数组的一层键,只会把根标签下的直接子元素作为数组的顶级键。
这就导致你写的isset($finalJson['ErrorResponse'])判断条件永远为假,所有请求都会走到else分支,直接输出IsPartnered字段的值,这就是你无论什么场景都只返回true的根本原因。
第二,之前测试array_key_exists('Error')没生效,是测试逻辑不同步
你打印的错误场景数组里,明确存在顶级键Error,只要判断这个键是否存在,就能正确识别错误响应。如果之前测试没生效,大概率是修改判断逻辑后,没有替换测试用的响应样本,一直拿成功场景的请求跑测试,自然走不到错误分支。
修正后的可运行代码
$parsed_xml = json_encode(simplexml_load_string($response)); $finalJson = json_decode($parsed_xml, true); // 直接匹配实际存在的错误专属顶级键 if (array_key_exists('Error', $finalJson)) { // 错误场景处理 dd([ '错误类型' => $finalJson['Error']['Type'], '错误码' => $finalJson['Error']['Code'], '错误信息' => $finalJson['Error']['Message'] ]); } else { // 成功场景取值,注意逐层判断键存在性避免报错 if (isset($finalJson['GetTransportContentResult']['TransportContent']['TransportHeader']['IsPartnered'])) { dd($finalJson['GetTransportContentResult']['TransportContent']['TransportHeader']['IsPartnered']); } // 补全结构缺失的兜底逻辑 dd('响应结构不完整,无法获取运输信息'); }
额外注意事项
- SimpleXML转出来的单值节点都是字符串类型,比如
IsPartnered的值是字符串"true",不是布尔型的true,后续做逻辑判断时要注意类型转换。 - 不要依赖XML根标签名做判断,因为转数组的过程中已经丢失了根标签层级信息,直接匹配业务专属的顶级键(错误场景的
Error、成功场景的GetTransportContentResult)才是和实际数据结构完全匹配的可靠方案。 - 取值时必须逐层判断键是否存在,避免接口返回的结构缺层时触发PHP未定义键的警告/报错。
内容的提问来源于stack exchange,提问作者Mhell Anthonet Bitanas
相关产品推荐
相关产品推荐

