2010-11-30 62 views
5

我一直在嘗試一段時間,但我無法弄清楚如何將PHP SoapCLient與WSDL結合使用來形成一個複雜的標題(也就是說,比任何教程更復雜能找到)。我需要發送看起來像這樣的信封:我試過PHP SoapClient和一個複雜的標題

(001) <?xml version='1.0' encoding='UTF-8'?> 

(002) <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xlink="http://www.w3.org/1999/xlink"> 

(003) <SOAP-ENV:Header> 

(004) <eb:MessageHeader xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:version="2.0" SOAP-ENV:mustUnderstand="1"> 

(005) <eb:From> 

(006) <eb:PartyId>webservices.example.com</eb:PartyId> 

(007) </eb:From> 

(008) <eb:To> 

(009) <eb:PartyId>clientURL</eb:PartyId> 

(010) </eb:To> 

(011) <eb:CPAId>IPCC</eb:CPAId> 

(012) <eb:ConversationId>[email protected]</eb:ConversationId> 

(013) <eb:Service eb:type="XML">Session</eb:Service> 

(014) <eb:Action>SessionCreateRS</eb:Action> 

(015) <eb:MessageData> 

(016) <eb:MessageId>mid:[email protected]</eb:MessageId> 

(017) <eb:Timestamp>2001-02-15T11:25:12Z</eb:Timestamp> 

(018) </eb:MessageData> 

(019) <RefToMessageId>mid:[email protected]</RefToMessageId> 

(020) </eb:MessageHeader> 

(021) <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/12/secext"> 

(022) <wsse:BinarySecurityToken xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/12/utility" wsu:Id="SabreSecurityToken" valueType="String" EncodingType="wsse:Base64Binary">Shared/IDL:IceSess\/SessMgr:1\.0.IDL/Common/!ICESMS\/RESC!ICESMSLB\/RES.LB!-4954987477210575357!252506!0</wsse:BinarySecurityToken> 

(023) </wsse:Security> 

(024) </SOAP-ENV:Header> 

(025) <SOAP-ENV:Body> 

(026) <eb:Manifest xmlns:eb="http://www.ebxml.org/namespaces/messageHeader" eb:version="2.0"> 

(027) <eb:Reference eb:id="SessionCreateRS" xlink:type="simple" xlink:href="cid:SessionCreateRS" 

(028) <eb:Description xml:lang="en-US">Response Message</eb:Description>"/> 

(029) </eb:Reference> 

(030) </eb:Manifest> 

(031) </SOAP-ENV:Body> 

(032) </SOAP-ENV:Envelope> 

使用它__setSoapHeaders(),並使用SoapVar()進行。雖然我無法獲得正確的輸出結果。從例子我瞭解到這將是很好用的一類,填補了XML的參數,所以我做了一個這樣的類:

class EbXmlMessage{ 
public $From = array('PartyId' => '[email protected]'); 
public $To = array('PartyId' => 'example.com'); 
public $CPAId = 'XXXX'; 
public $ConversationId = '[email protected]'; 
public $Service = 'Session'; 
public $Action = 'SessionCreateRQ'; 
public $MessageData = array('MessageId' => "mid:[email protected]",'Timestamp' => '2010-11-26T08:19:00Z'); 
} 

比我用:

$eb_params = new SoapVar($eb,SOAP_ENC_OBJECT); 
$header = new SoapHeader($ns,"header", $eb_params,true); 

,但該請求不甚至略微開始看起來像它具有:

<?xml version="1.0" encoding="UTF-8"?> 
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://www.opentravel.org/OTA/2002/11" xmlns:ns2="https://cert.webservices.sabre.com/cert"> 
<SOAP-ENV:Header> 
    <ns2:header SOAP-ENV:mustUnderstand="1"> 
    <From> 
    <item> 
    <key>PartyId</key> 
    <value>[email protected]</value> 
    </item> 
    </From> 
    <To> 
    <item> 
    <key>PartyId</key> 
    <value>webservices.sabre.com</value> 
    </item> 
    </To> 
    <CPAId>XXX</CPAId> 
    <ConversationId>[email protected]</ConversationId> 
    <Service>Session</Service> 
    <Action>SessionCreateRQ</Action> 
    <MessageData> 
    <item> 
    <key>MessageId</key> 
    <value>mid:[email protected]</value> 
    </item> 
    <item> 
    <key>Timestamp</key> 
    <value>2010-11-26T08:19:00Z</value> 
    </item> 
    </MessageData> 
    </ns2:header> 
</SOAP-ENV:Header> 
<SOAP-ENV:Body> 
    <ns1:SessionCreateRQ> 
    <ns1:POS> 
    <ns1:Source PseudoCityCode="XXXX"/> 
    </ns1:POS> 
    </ns1:SessionCreateRQ> 
    <param1/> 
</SOAP-ENV:Body> 
</SOAP-ENV:Envelope 

的主要問題至今越來越在正確的地方的XML正確標記,我不知道我怎樣才能得到「EB」和標籤中的「wsse:」命名空間秒。我希望能夠使用SoapClientI()類,但我不確定它是否可以像我需要的那樣處理更復雜的XML,如果不是,我可能應該使用Curl或類似的東西,並將XML作爲字符串處理?

+0

手動修改字符串是不明智的,因爲它很難維護。如果你能讓客戶端正確地對付wsdl,即使考慮到奇怪的命名空間問題,那也可能是值得的。 – zanlok 2010-11-30 22:11:54

回答

10

我在使用wsse時遇到了問題。這是我的方法。是的,這是非常具體的;但是,它也應該適用於您的情況。特別注意在new SoapHeader()調用中如何存在'wsse'命名空間參數。只需將它替換爲'eb'即可。

$header_part = ' 
    <wsse:Security xmlns:wsse="http://schemas.xmlsoap.org/ws/2003/06/secext" SOAP-ENV:mustUnderstand="1"> 
     <wsse:UsernameToken> 
      <wsse:Username>'."USERNAME".'</wsse:Username> 
      <wsse:Password>'."PASSWORD".'</wsse:Password> 
     </wsse:UsernameToken> 
    </wsse:Security> 
'; 
$soap_var_header = new SoapVar($header_part, XSD_ANYXML, null, null, null); 
$soap_header = new SoapHeader('http://your-target-service.com', 'wsse', $soap_var_header); 
$soap_client->__setSoapHeaders($soap_header); 

另一種解決方案是在繼承SoapClient的子類之後對XML進行破壞,但我只會將其作爲最後的手段。

class My_SoapClient extends SoapClient { 
    protected $_response = null; 
    public function __doRequest($request, $location, $action, $version, $one_way=null) { 
     // insert big bad mangling code here 
     $this->_response = parent::__doRequest($this->_request, $location, $action, $version, $one_way); 
     return $this->_response; 
    } 
} 
0

這樣做是利用覆蓋的curl功能__doRequest的一種可能方式。有一個示例here,它顯示如何關閉KeepAlive