PHP Curl获取XML接口响应后的解析与节点提取方法
问题说明
现有基于PHP cURL开发的库存接口请求脚本存在两个待解决问题:
- 直接echo输出响应时,页面显示的SKU值为
210-AZBVTBC,但Chrome开发者工具中查到接口实际返回SKU为210-AZBVTBC4,存在显示差异 - 无法解析XML格式的响应内容,不能单独提取、自定义操作单个XML标签内的数据,无法实现类似
echo $response->Sku.'<br>';的取值效果
原有代码如下:
$curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://www.xxxxx.com/webAPI/api/stock', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 0, CURLOPT_FOLLOWLOCATION => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_POSTFIELDS =>'<?xml version="1.0" encoding="utf-8" ?> <traderapi> <token>T1a5c3t9</token> <variant>Clearbank ltd</variant> <pon>X</pon> </traderapi>', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer T1a5c3t9', 'Content-Type: application/xml' ), )); $response = curl_exec($curl); curl_close($curl); echo $response ?>
解决方案
1. 修复返回值显示截断问题
显示差异不是接口返回错误,也不是cURL传输丢数据,核心原因是直接echo XML内容时,浏览器默认按HTML规则解析页面,XML的尖括号标签会被识别为未知HTML元素,触发浏览器HTML容错机制导致部分内容被截断不显示。
修复方法:
- 输出原始响应前对内容做HTML实体转义,避免浏览器解析XML标签
- 增加cURL错误判断、响应长度校验,排除传输层异常
2. 实现XML响应解析
PHP内置SimpleXML扩展可以直接将XML格式字符串转为可访问的对象,直接通过对象属性语法即可读取对应节点的值,无需额外安装依赖。
修复后完整可运行代码
<?php $curl = curl_init(); curl_setopt_array($curl, array( CURLOPT_URL => 'https://www.xxxxx.com/webAPI/api/stock', CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => '', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, // 建议设置合理超时时间,不要用0无限等待 CURLOPT_FOLLOWLOCATION => false, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_POSTFIELDS =>'<?xml version="1.0" encoding="utf-8" ?> <traderapi> <token>T1a5c3t9</token> <variant>Clearbank ltd</variant> <pon>X</pon> </traderapi>', CURLOPT_HTTPHEADER => array( 'Authorization: Bearer T1a5c3t9', 'Content-Type: application/xml' ), )); $response = curl_exec($curl); // 捕获cURL请求错误 if(curl_errno($curl)){ die("cURL请求失败:" . curl_error($curl)); } // 可选:核对响应长度,确认传输完整 $httpInfo = curl_getinfo($curl); curl_close($curl); // 如需查看完整原始响应,取消下方注释即可,转义后不会被浏览器截断 // echo "<pre>原始响应内容:<br>"; // echo htmlspecialchars($response); // echo "</pre><hr>"; // 解析XML响应 $xmlObj = simplexml_load_string($response); if(!$xmlObj){ die("XML格式解析失败"); } // 直接按节点名取值即可 // 注意:如果节点是嵌套结构,按层级写属性即可,例如$xmlObj->item->Sku // 存在多个同名同级节点时,用下标取对应项,例如$xmlObj->item[0]->Sku取第一个item节点下的Sku echo "SKU值:" . $xmlObj->Sku . "<br>"; ?>
内容的提问来源于stack exchange,提问作者Matthew Payton
相关产品推荐
相关产品推荐

