如何将SOAP Env API响应转换为PHP数组或JSON数组
简便转换SOAP响应为PHP数组/JSON的方法
嘿,我之前也碰到过类似的SOAP XML转数组/JSON的需求,给你分享两个亲测好用的简便方法,不用折腾复杂的第三方库,用PHP自带的功能就能搞定!
方法1:处理已拿到的SOAP XML字符串
如果你已经获取到了像你贴出来的XML响应,咱们可以用SimpleXML来解析,再转成数组或JSON。关键是要处理好XML里的命名空间,不然拿不到正确的节点。
代码示例:
// 把你的SOAP响应XML字符串放这里 $soapXml = '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"> <SOAP-ENV:Header/> <SOAP-ENV:Body> <ns6:getLocationByCriteriaResponse xmlns:ns6="http://api.atdconnect.com/atd/3_4/locations" xmlns:c="http://api.atdconnect.com/atd/3_4/common" xmlns:f="http://api.atdconnect.com/atd/3_4/fitments" xmlns:o="http://api.atdconnect.com/atd/3_4/orders" xmlns:p="http://api.atdconnect.com/atd/3_4/products"> <ns6:locations> <ns6:location> <ns6:locationNumber>1104464</ns6:locationNumber> <ns6:locationName>CONCORDE AUTOMOBILE 1990 LTEE</ns6:locationName> <ns6:phoneNumber>4507745336</ns6:phoneNumber> <ns6:customerNumber>507281</ns6:customerNumber> <ns6:address> <c:address1>3003 RUE PICARD</c:address1> <c:city>SAINT-HYACINTHE</c:city> <c:state>QC</c:state> <c:zipCode>J2S1H2</c:zipCode> </ns6:address> <ns6:servicingDC>866</ns6:servicingDC> </ns6:location> <ns6:location> <ns6:locationNumber>1106909</ns6:locationNumber> <ns6:locationName>CORONADO LUBE</ns6:locationName> <ns6:phoneNumber>9154404222</ns6:phoneNumber> <ns6:customerNumber>507281</ns6:customerNumber> <ns6:address> <c:address1>6508 ESCONDIDO DR</c:address1> <c:city>EL PASO</c:city> <c:state>TX</c:state> <c:zipCode>79912</c:zipCode> </ns6:address> <ns6:servicingDC>615</ns6:servicingDC> </ns6:location> </ns6:locations> </ns6:getLocationByCriteriaResponse> </SOAP-ENV:Body> </SOAP-ENV:Envelope>'; // 加载XML到SimpleXMLElement对象 $xml = new SimpleXMLElement($soapXml); // 注册XML里用到的命名空间,不然xpath找不到节点 $xml->registerXPathNamespace('ns6', 'http://api.atdconnect.com/atd/3_4/locations'); $xml->registerXPathNamespace('c', 'http://api.atdconnect.com/atd/3_4/common'); // 用xpath提取所有location节点 $locationNodes = $xml->xpath('//ns6:location'); // 定义一个递归函数,把SimpleXML对象转成普通数组 function xmlToPhpArray($xmlNode, $result = []) { foreach ((array)$xmlNode as $key => $value) { $result[$key] = is_object($value) || is_array($value) ? xmlToPhpArray($value) : (string)$value; } return $result; } // 把每个location转成数组,收集到结果里 $locationArray = []; foreach ($locationNodes as $node) { $locationArray[] = xmlToPhpArray($node); } // 转成JSON的话直接用json_encode $locationJson = json_encode($locationArray, JSON_PRETTY_PRINT); // 输出结果看看 print_r($locationArray); echo "\nJSON格式:\n" . $locationJson;
关键点说明:
- 必须注册命名空间:你的XML里有
ns6和c两个命名空间,注册后才能用xpath精准定位到节点。 - 递归转换:SimpleXML对象不能直接转数组,所以用递归函数把所有子节点都转成普通PHP数组。
- 如果要JSON,直接用
json_encode就能把数组转成格式化好的JSON字符串。
方法2:直接用SoapClient调用API并获取数组
如果还没调用API,建议直接用PHP的SoapClient类来发起请求,它能自动处理SOAP的封装和解封,直接拿到结构化的对象,再转成数组就超简单了。
代码示例:
try { // 初始化SoapClient,传入WSDL地址(如果有的话) $soapClient = new SoapClient('http://api.atdconnect.com/atd/3_4/locations?wsdl', [ 'trace' => true, // 开启trace方便调试 'exceptions' => true, // 开启异常捕获 'features' => SOAP_SINGLE_ELEMENT_ARRAYS // 确保单个元素也返回数组,避免后续处理报错 ]); // 构造请求参数(根据API要求调整) $requestParams = [ // 这里填你的查询条件,比如criteria参数 ]; // 调用API方法 $response = $soapClient->getLocationByCriteria($requestParams); // 把响应对象转成数组:先转JSON再转数组,一步到位 $responseArray = json_decode(json_encode($response), true); // 提取locations数据(根据响应结构调整) $locations = $responseArray['getLocationByCriteriaResponse']['locations']['location']; print_r($locations); } catch (SoapFault $e) { // 处理错误 echo "请求出错:" . $e->getMessage(); }
优势:
- 不用手动处理XML,
SoapClient会帮你搞定所有SOAP协议相关的细节。 - 直接获取结构化对象,转数组只需要一行代码,省心又不容易出错。
这两种方法都很简便,你可以根据自己的实际情况选一个来用~
内容的提问来源于stack exchange,提问作者Mike Taylor
相关产品推荐
相关产品推荐

