SOAP has been described by many as an easy way to build and consume web services. Up until yesterday, my opinion of that was greatly different. One 3 separate projects, we had found 2 different ways to get it to work properly, none of them the same. On 2 we resorted to using cURL and posting them ourselves! Yikes!
So, our issue was that, no matter how we sent the data to the web service, one of the XML nodes was always empty. No matter how we build the parameters to pass, it was never there.
I was aware of using the __getFunctions() call, but sadly I was not aware of the __getTypes() PHP function. Combining these, I was able to see what was needed. Running them both on the web service in question, gave me valuable insight on the method I was working on.
print_r($_client->__getFunctions());
Array
(
…
[1] => OrderInteractiveResponse OrderInteractive(OrderInteractive $parameters)
…
)print_r($_client->__getTypes());
Array
(
…
[4] => struct OrderInteractive {
string inCommunications;
OrderEntity inOrder;
}
[5] => struct OrderEntity {
string OrderXml;
}
…
So, the OrderInteractive method is first looking for a string “inCommunications” that, in this case, was an XML string of access parameters that I already had built from samples provided by the web service.
The second is an object “inOrder” that is looking for a string “OrderXml” that is another XML string I also already built and had ready (BTW: this is the string that never appeared in the SOAP request). So, seeing this, I was able to build the full SOAP parameters to pass to the web service. My final code looks like:
// create a class for your webservice structure
class inOrder {
function inOrder($xml) {
$this->OrderXml = $xml;
}
}// WSDL URL (set in `config`)
$soap_url = API_URL;
$soap_params = array(
‘trace’ => true,
‘exceptions’ => true,
‘cache_wsdl’ => false
);// create our client
$_client = new SoapClient($soap_url, $soap_params);// set the communication info
$xml_communication = ‘OnlineBLAH…’;// create the order information
$xml_order = ‘OLDL…’;// create our order object that is needed
$order = new inOrder($xml_order);// create our OrderInteractive parameters
$parameters = array(
“inCommunications” => $xml_communication,
“inOrder” => $order
);try {
$xml = $_client->OrderInteractive($parameters);
} catch (Exception $e) {
print $e->getMessage() . “\n”; exit();
}
I named the class “inOrder” to match the “OrderEntity inOrder” from the __getTypes() call. In it I set the name of “OrderXml” to the value of my XML order string.
When I ran this, I got the expected results!
Short story is: determine the method call with __getFunctions() and then see how that data needs to be passed with __getTypes(). Once I did that, it was clear sailing! I may, again, have issues w/ SOAP down the road, but hopefully this will help me (and others).
Side note: two other invaluable functions for the PHP SoapClient are the __getLastRequest() and __getLastResponse() functions. The former allowed me to see that my “inOrder” object was always empty.
Happy coding!