tags:

views:

1064

answers:

2

Doing some SOAP calls to a 3rd party application. They provide this soap header as an example of what the application expects. How can I create a SOAP header like this in PHP?

<SOAP-ENV:Header>
 <NS1:Security xsi:type="NS2:Security" xmlns:NS1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:NS2="urn:dkWSValueObjects">
  <NS2:UsernameToken xsi:type="NS2:TUsernameToken">
   <Username xsi:type="xsd:string">XXXX</Username> 
   <Password xsi:type="xsd:string">XXX</Password> 
  </NS2:UsernameToken>
 </NS1:Security>
</SOAP-ENV:Header>

I do what i think is a correct call and keep getting in return that no headers were sent.

Here is a sample from my code.

class SOAPStruct 
{
    function __construct($user, $pass) 
    {
        $this->Username = $user;
        $this->Password = $pass;
    }
}

$client = new SoapClient("http://www.example.com/service");

$auth = new SOAPStruct("username", "password");
$header = new SoapHeader("http://example.com/service", "TUsernameToken", $auth);

$client->__setSoapHeaders(array($header));
$client->__soapCall("GetSubscriptionGroupTypes", array(), NULL, $header)

And this is the SOAP header i get back. (its more but i stripped info away that might be sensitive)

<SOAP-ENV:Header>
 <ns2:TUsernameToken>
  <Username>username</Username> 
  <Password>password</Password> 
 </ns2:TUsernameToken>
</SOAP-ENV:Header>
A: 

Aren't there PHP libraries for SOAP handling, that can generate PHP objects and Service interfaces from the WSDL / XSD for the web service?

JeeBee
I am using the SOAPClient library in PHP.
Ólafur Waage
+2  A: 

SOAP header handling in PHP is actually not very flexible and I'd go as far as saying that especially the use two namespaces within the header will make it impossible to inject the header simply by using a SoapHeader-construct of some type.

I think the best way to handle this one is to shape the XML request yourself by overriding SoapClient::__doRequest() in a custom class that extends SoapClient.

class My_SoapClient extends SoapClient
{
    public function __doRequest($request, $location, $action, $version, $one_way = 0)
    {
        $xmlRequest = new DOMDocument('1.0');
        $xmlRequest->loadXML($request);

        /*
         * Do your processing using DOM 
         * e.g. insert security header and so on
         */

        $request = $xmlRequest->saveXML();
        return parent::__doRequest($request, $location, $action, $version, $one_way);
    }
}

Please see SoapClient::__doRequest for further information and some examples.

Stefan Gehrig
I did in the end create my own header, but with nuSOAP, but your answer led me the right way. :)
Ólafur Waage