How to use nuSOAP for messages with multiple namespaces

After trying around with the matching, I found two possible solutions:

1) Don't use the WSDL to create the nusoap_client and soapval() to create the message This has the disadvantage that the message contains a lot of overhead (the namespace is defined in each element). Not so fine.

2) Instead of relying on the matching of parameters, construct your reply in xml and put all the definition for prefixes in the first element - e.g.

$params = "<ns1:myOperation xmlns:ns1="..." xmlns:ns2="...">
      <ns2:Person>
        <ns2:Firstname>..</ns2:Firstname>
        ..
      </ns2:Person>
      <ns1:Attribute>..</ns1:Attribute>
    </ns1:myOperation>";

Still not a very nice solution, but it works :-)


Building on Irwin's post, I created the xml manually and had nusoap do the rest. My webhost does not have the php soap extension, so I had to go with nusoap, and the web service I'm trying to consume required the namespaces on each tag (e.g. on username and password in my example here).

require_once('lib/nusoap.php');

$client = new nusoap_client('https://service.somesite.com/ClientService.asmx');
$client->soap_defencoding = 'utf-8';
$client->useHTTPPersistentConnection(); // Uses http 1.1 instead of 1.0
$soapaction = "https://service.somesite.com/GetFoods";

$request_xml = '<?xml version="1.0" encoding="utf-8" ?>
<env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
  <env:Body>
    <n1:GetFoods xmlns:n1="https://service.somesite.com">
      <n1:username>banjer</n1:username>
      <n1:password>theleftorium</n1:password>
    </n1:GetFoods>
  </env:Body>
</env:Envelope>
';

$response = $client->send($request_xml, $soapaction, ''); 

echo '<h2>Request</h2><pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2><pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>';

Then I had an error that said:

Notice: Undefined property: nusoap_client::$operation in ./lib/nusoap.php  on line 7674

So I went the lazy route and went into nusoap.php and added this code before line 7674 to make it happy:

    if(empty($this->operation)) {
        $this->operation = "";
    }

Another bypass this issue would be a modification to nusoap_client::call() function. Next to the this line (7359 in version 1.123) in nusoap.php:

$nsPrefix = $this->wsdl->getPrefixFromNamespace($namespace);

I added this one:

$nsPrefix = $this->wsdl->getPrefixFromNamespace("other_ns_name");

And it worked! Since I only needed this library for one project, it was OK for me to hardcode this hack. Otherwise, I would dig more and modify the function to accept array instead of string for a namespace parameter.