Question

I am using PHP SoapClient in WSDL mode.

This is what the expected SOAP request should look like:

<soapenv:Envelope 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" 
xmlns:ns="http://xml.m4u.com.au/2009"> 
<soapenv:Header/> 
<soapenv:Body> 
 <ns:sendMessages> 
   <ns:authentication> 
     <ns:userId>Username</ns:userId> 
     <ns:password>Password</ns:password> 
   </ns:authentication> 
   <ns:requestBody> 
     <ns:messages> 
       <ns:message> 
         <ns:recipients> 
           <ns:recipient>61400000001</ns:recipient>  
         </ns:recipients> 
         <ns:content>Message Content</ns:content> 
       </ns:message> 
     </ns:messages> 
   </ns:requestBody> 
 </ns:sendMessages> 
</soapenv:Body> 
</soapenv:Envelope> 

And this is what PHP SoapClient is sending:

<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:ns1="http://xml.m4u.com.au/2009">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns1:sendMessages>
  <ns1:authentication>
    <userId>Username</userId>
    <password>Password</password>
  </ns1:authentication>
  <ns1:requestBody>
    <messages>
      <message>
        <recipients>
          <recipient>61400000001</recipient>
        </recipients>
        <content>Message Content</content>
      </message>
    </messages>
  </ns1:requestBody>
</ns1:sendMessages>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

This is how I constructed the client and params:

function sendMessages($recipient, $content) {

    $authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);

    $recipientsType = new SoapVar(array('recipient' => $recipient), SOAP_ENC_OBJECT);
    $messageType = new SoapVar(array('recipients' => $recipientsType, 'content' => $content), SOAP_ENC_OBJECT);
    $messagesType = new SoapVar(array('message' => $messageType), SOAP_ENC_OBJECT);

    $requestBodyType = new SoapVar(array('messages' => $messagesType), SOAP_ENC_OBJECT);

    $params = array(
                'authentication' => $authenticationType,
                'requestBody' => $requestBodyType
            );

    try {
        $this->soapClient = new SoapClient($this->wsdl, array('trace' => 1));
        $this->soapClient->__setSoapHeaders(array());

        return $this->soapClient->sendMessages($params);

    } catch (SoapFault $fault) {
        echo '<h2>Request</h2><pre>' . htmlspecialchars($this->soapClient->__getLastRequest(), ENT_QUOTES) . '</pre>';
        trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faultstring})", E_USER_ERROR);
    }

}

Why is 'ns1' present for 'authentication' and 'requestBody' but missing for their child nodes? What am I doing wrong? The WSDL is located here => http://soap.m4u.com.au/?wsdl

Appreciate anyone who can help.

Was it helpful?

Solution

You must specify the URI of the namespace to encode the object. This will include everything necessary (including your missing namespace). The acronym of the namespace name is irrelevant.

This:

$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT);

should be:

$authenticationType = new SoapVar(array('userId' => $this->username, 'password' => $this->password), SOAP_ENC_OBJECT, "authentication","http://xml.m4u.com.au/2009");

The problem you're seeing with the namespace serialization comes from using soapvar without all the parameters. When it serializes the request prior to sending it assumes the namespace is already included. If, instead, you had created each as a simple array and included them in $params it would include the namespace for the internal parameters correctly. By way of demonstration:

$authenticationType = array('userId' => $this->username, 'password' => $this->password)

OTHER TIPS

try using nusoap library. Below is sample code:

<?php
$wsdl = "http://soap.m4u.com.au/?wsdl";
// generate request veriables
$data = array();

$action = ""; // ws action
$param = ""; //parameters

$options = array(
            'location'  => 'http://soap.m4u.com.au',
            'uri'       => ''
            );
// eof generate request veriables

//$client = new soap_client($wsdl, $options);// create soap client
$client = new nusoap_client($wsdl, 'wsdl');

$client->setCredentials($api_username, $api_password);// set crendencials
$opt = $client->call($action, $param, '', '', false, true);

print_r($opt);
?>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top