Как создать запрос SOAP PHP с несколькими пространствами имен

Я пытаюсь получить цитату из службы SOAP. Я смог успешно создать заголовки аутентификации и запросить службу SOAP с базовыми запросами, для которых не требуются параметры тела.

Я могу создать надлежащую структуру для запроса, но значения пространства имен не отображаются в выводе запроса.

Пример кода:

$client = new SoapClient("http://demo.smc3.com/AdminManager/services/RateWareXL?wsdl", array('trace' => TRUE)); $headerParams = array('ns1:licenseKey' => $key, 'ns1:password' => $pass, 'ns1:username' => $user); $soapStruct = new SoapVar($headerParams, SOAP_ENC_OBJECT); $header = new SoapHeader($ns, 'AuthenticationToken', $soapStruct, false); $client->__setSoapHeaders($header); // Check if shipping is ready - base call $ready_to_ship = $client->isReady(); 

Вышеуказанное работает просто отлично и возвращает true, если служба доставки доступна.

Поэтому я использую следующий код для создания тела запроса (только заполнение обязательных полей): я также попытался поместить все в массив и преобразовать его в SoapVar, я попытался включить ns1: и ns2: в создании запроса тела но это тоже не сработало. Я считаю, что что-то нужно скорректировать при создании запроса … не уверен в наилучшем подходе.

 $rate_request = $client->LTLRateShipment; $rate_request->LTLRateShipmentRequest->destinationCountry = $destination_country; $rate_request->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; $rate_request->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; $rate_request->LTLRateShipmentRequest->details->LTLRequestDetail->nmfcClass = $ship_class; $rate_request->LTLRateShipmentRequest->details->LTLRequestDetail->weight = $ship_weight; $rate_request->LTLRateShipmentRequest->originCountry = $origin_country; $rate_request->LTLRateShipmentRequest->originPostalCode = $origin_postal_code; $rate_request->LTLRateShipmentRequest->shipmentDateCCYYMMDD = $ship_date; $rate_request->LTLRateShipmentRequest->tariffName = $tariff; 

И он создает следующий XML:

 <?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://webservices.smc.com"> <SOAP-ENV:Header> <ns1:AuthenticationToken> <ns1:licenseKey>xxxxxxxx</ns1:licenseKey> <ns1:password>xxxxxxxx</ns1:password> <ns1:username>xxxxxxxxm</ns1:username> </ns1:AuthenticationToken> </SOAP-ENV:Header> <SOAP-ENV:Body> <ns1:LTLRateShipment> <LTLRateShipmentRequest> <destinationCountry>USA</destinationCountry> <destinationPostalCode>10001</destinationPostalCode> <details> <LTLRequestDetail> <nmfcClass>60</nmfcClass> <weight>300</weight> </LTLRequestDetail> </details> <originCountry>USA</originCountry> <originPostalCode>90210</originPostalCode> <shipmentDateCCYYMMDD>20110516</shipmentDateCCYYMMDD> <tariffName>DEMOLTLA</tariffName> </LTLRateShipmentRequest> </ns1:LTLRateShipment> </SOAP-ENV:Body> </SOAP-ENV:Envelope> 

Но вывод должен включать пространства имен (web: и web1: где это необходимо). Вышеуказанный запрос возвращает код ошибки отсутствующего имени тарифа.

Вот пример того, как должен выглядеть запрос xml:

  <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservices.smc.com" xmlns:web1="http://web.ltl.smc.com"> <soapenv:Header> <web:AuthenticationToken> <web:licenseKey> string </web:licenseKey> <web:password> string </web:password> <web:username> string </web:username> </web:AuthenticationToken> </soapenv:Header> <soapenv:Body> <web:LTLRateShipment> <web:LTLRateShipmentRequest> <web1:LTL_Surcharge> string </web1:LTL_Surcharge> <web1:TL_Surcharge> string </web1:TL_Surcharge> <web1:destinationCity> string </web1:destinationCity> <web1:destinationCountry> string </web1:destinationCountry> <web1:destinationPostalCode> string </web1:destinationPostalCode> <web1:destinationState> string </web1:destinationState> <web1:details> <!--Zero or more repetitions:--> <web1:LTLRequestDetail> <web1:nmfcClass> string </web1:nmfcClass> <web1:weight> string </web1:weight> </web1:LTLRequestDetail> </web1:details> <web1:discountApplication> string </web1:discountApplication> <web1:mcDiscount> string </web1:mcDiscount> <web1:orgDestToGateWayPointFlag> string </web1:orgDestToGateWayPointFlag> <web1:originCity> string </web1:originCity> <web1:originCountry> string </web1:originCountry> <web1:originPostalCode> string </web1:originPostalCode> <web1:originState> string </web1:originState> <web1:rateAdjustmentFactor> string </web1:rateAdjustmentFactor> <web1:shipmentDateCCYYMMDD> string </web1:shipmentDateCCYYMMDD> <web1:shipmentID> string </web1:shipmentID> <web1:stopAlternationWeight> string </web1:stopAlternationWeight> <web1:surchargeApplication> string </web1:surchargeApplication> <web1:tariffName> string </web1:tariffName> <web1:weightBreak_Discount_1> string </web1:weightBreak_Discount_1> </web:LTLRateShipmentRequest> </web:LTLRateShipment> </soapenv:Body> </soapenv:Envelope> 

Любые предложения / руководство оценили!

Хорошо … После слишком многих часов тестирования у меня наконец есть решение.

Я воссоздал токен авторизации как класс и построил запрос Soap без необходимости иметь дело с любыми пространствами имен, SoapVars и т. Д., Это на удивление легко.

 /* Object for holding authentication info this could probably be accomplished using stdClass too */ class AuthHeader { var $licenseKey; var $password; var $username; function __construct($loginInfo) { $this->licenseKey = $loginInfo['licenseKey']; $this->password = $loginInfo['password']; $this->username = $loginInfo['username']; } } // set current soap header with login info $client = new SoapClient("http://demo.smc3.com/AdminManager/services/RateWareXL?wsdl", array('trace' => TRUE )); // create header params array $headerParams = array('licenseKey' => $key, 'password' => $pass, 'username' => $user); // create AuthHeader object $auth = new AuthHeader($headerParams); // Turn auth header into a SOAP Header $header = new SoapHeader($ns, 'AuthenticationToken', $auth, false); // set the header $client->__setSoapHeaders($header); // Check if shipping is ready - base call $ready_to_ship = $client->isReady(); // $last_request = $client->__getLastRequest(); $last_response = $client->__getLastResponse(); //print $last_request; if ($last_response == true) { print "Ready to ship\n"; // Create the shipping request $d = new stdClass; $d->nmfcClass = $ship_class; $d->weight = $ship_weight; $p = new stdClass; $p->LTLRateShipmentRequest->destinationCountry = $destination_country; $p->LTLRateShipmentRequest->destinationPostalCode = $destination_postal_code; $p->LTLRateShipmentRequest->details = array($d); $p->LTLRateShipmentRequest->originCountry = $origin_country; $p->LTLRateShipmentRequest->originPostalCode = $origin_postal_code; $p->LTLRateShipmentRequest->shipmentDateCCYYMMDD = $ship_date; $p->LTLRateShipmentRequest->tariffName = $tariff; $quote = $client->LTLRateShipment($p); $last_request = $client->__getLastRequest(); $last_response = $client->__getLastResponse(); print "Request: " . $last_request; print "\nResponse: " . $last_response; }