2011-05-13 187 views
6

我试图从SOAP服务获取运输报价。我已经能够成功地创建验证标头,并使用不需要主体参数的基本请求来查询SOAP服务。如何使用多个命名空间创建PHP 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> 

任何建议/方向赞赏!

回答

6

好吧......经过测试的太多时间,我终于有一个解决方案..

我重新授权令牌作为一类和内置的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; 

}