2011-05-13 84 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; 

}