Mar 30
Consuming ColdFusion webservices from PHP
Posted by James Netherton | Friday 30 March 2007 3:27 PM | In PHP,ColdFusion
If you expose a ColdFusion component as a webservice and have arguments or a return type of type struct. In the resulting webservice WSDL, the struct is represented as a complexType.
To see what I mean, I've created an example CF webservice component:
<cffunction name="exampleMethod" access="remote" returntype="struct">
<cfargument name="personName" type="string"/>
<cfargument name="personDetails" type="struct"/>
</cffunction>
</cfcomponent>
Here's a snippet of how the struct data type is represented within the WSDL:
<wsdl:message name="exampleMethodRequest">
<wsdl:part name="personName" type="xsd:string"/>
<wsdl:part name="personDetails" type="apachesoap:Map"/>
</wsdl:message>
Note that the personDetails parameter is of type apachesoap:Map. Here's the definition for apachesoap:Map:
<sequence>
<element name="key" nillable="true" type="xsd:anyType"/>
<element name="value" nillable="true" type="xsd:anyType"/>
</sequence>
</complexType>
As we'd expect, it's a simple key / value hashmap which is essentially what the CF struct is.
No lets add some simple logic into the webservice method that I showed earlier:
<cffunction name="exampleMethod" access="remote" returntype="struct">
<cfargument name="personName" type="string"/>
<cfargument name="personDetails" type="struct"/>
<!--- Create a response strcure --->
<cfset var result = structNew()/>
<!---
Just build up a big list containing the info we
got from the personDetails argument
--->
<cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personName)/>
<cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["age"])/>
<cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["gender"])/>
<cfset result["personProfile"] = listAppend(result["personProfile"],arguments.personDetails["dob"])/>
<cfreturn result/>
</cffunction>
</cfcomponent>
Nothing too complicated going on there. The service expects a string argument and a structure which is expected to contain age, gender and dob keys. Creating a webservice call to invoke this service in ColdFusion would be an extremely simple task, but how would one use PHP to invoke this service?
It's more complicated than you probably think due to the usage of structs and complexTypes. After doing some research, returning structs, arrays and query data types from webservices is not best practice. There are many forum posts from PHP, .NET and Java developers who have encountered problems resolving these data types via webservice calls.
So how would one use PHP to pass the personDetails struct parameter to a ColdFusion webservice?
I'll be using nusoap to consume the webservice. Here's the PHP script:
//Import the SOAP library
require_once('nusoap.php');
//Get a handle to the webservice
$wsdl=new soapclient('http://myserver/example.cfc?wsdl',true);
/*
Define a class that represents the parameters being passed into the service:
- personName <string>
- personDetails <ColdFusion struct>
*/
class complexType{
//personName is a simple string
var $personName = 'Homer Simpson';
//personDetails is a CF struct so define as an associative array
var $personDetails = array('age'=>'35',
'gender'=>'Male',
'dob'=>'01/05/1971');
}
//Create an instance of the complexType object
$complex = new complexType;
$proxy = $wsdl->getProxy();
//Call the webservice exampleMethod method and pass in the parameters
$result = $proxy->exampleMethod($complex);
//Display the results contained in the personProfile element
echo($result["exampleMethodReturn"]["personProfile"]);
?>
Notice that the response is returned in an associative array with the top level element being named 'exampleMethodReturn'. If you look at the WSDL for the service, you'll see the definition for this:
<wsdl:part name="exampleMethodReturn" type="apachesoap:Map"/>
</wsdl:message>
And that's all there is to it!
0 Comments
[Post comment]