Getting complex with PHP and NuSOAP (Part 1)
I remember the first time I had to write some SOAP based web services in PHP that used complex data structures, it was back in the days before PHP 5 was considered production ready (by me at least…) so I didn’t have access to built in SOAP support, which lead me to discover the NuSOAP tool kit. These days I still use NuSOAP, partly out of laziness to get to grips with PHP 5’s SOAP support and because NuSOAP does some really cool stuff… like abstracting the process of making the WSDL so you don’t have to write out all that XML - after all these are web services, you shouldn’t have to see any XML right? And it even makes pretty html documentation for you!
As it’s cold out side, and in the absence of any kind of life, I thought I’d post a short example of how I structure NuSOAP stuff and how to use complex data structures. I’m going to spilt this into three posts: the first being a how to do a simple ‘complex type’, the next being an array of complex types and the third being a little AppleScript client to prove everything works. I’m doing it this way because writing about the code is actually really boring, not because I have any delusions that you’ll be sitting on the edge of you seat waiting for the next instalment!
The demo app is a phone list, all the database stuff is faked in the Person class, so the search will always return the same 5 results!
You can get all the source code for the entire app here: soapdemo.zip (including a version of NuSOAP that I moded to fix a bug with PHP 5)!
So, in a really patronising way, let’s look at the first function:
function getPerson($id) {
$person = Person::getPerson($id);
//load the data into an array with names and return it
return array('id' => $person->getID(),
'firstName' => $person->firstName,
'lastName' => $person->lastName,
'phoneNumber' => $person->phoneNumber
);
}
If this function was called with a ‘1′ as $id then a var_dump() of the result would look like this:
array(4) {
["id"]=>
int(1)
["firstName"]=>
string(6) "Donnie"
["lastName"]=>
string(5) "Darko"
["phoneNumber"]=>
string(11) "111 111 111"
}
So the question on every body’s lips is: How do you describe this structure to NuSOAP? Well it’s easy:
$server = new soap_server();
$server->configureWSDL('soapdemo_wsdl', 'urn:soapdemo_wsdl');
$server->wsdl->addComplexType('Person',
'complexType',
'struct',
'all',
'',
array(
'id' => array('name' => 'id',
'type' => 'xsd:int'),
'firstName' => array('name' => 'firstName',
'type' => 'xsd:string'),
'lastName' => array('name' => 'lastName',
'type' => 'xsd:string'),
'phoneNumber' => array('name' => 'phoneNumber',
'type' => 'xsd:string')
)
);
So what’s this code doing exactly? Well:
- In lines 1 and 2, we’re making a new instance of a NuSOAP server and saying what its WSDL will be called, that’s the XML file that tells our clients what our web services consist of.
- Add a complex data type called ‘Person’ to our SOAP server. The first four values get passed through to the WSDL, I’m not going to get into explaining what they do here… the array() that follows them tells NuSOAP what makes up our ‘Person’ structure:
- A thing called ‘id’, that will be refereed to as ‘id’ and is an integer
- A thing called ‘firstName’, that will be refereed to as ‘firstName’ and is a string
- and so on…
Next we have to register the function with NuSOAP:
$server->register('getPerson',
array('id' => 'xsd:int'),
array('return' => 'tns:Person'),
'soapdemo_wsdl',
'soapdemo_wsdl#getPerson',
'rpc',
'encoded',
'Returns the data for a person'
);
This code:
- Says there’s an available function called ‘getPerson’.
- That it accepts one integer referred to as ‘id’.
- It returns an object that is of type Person.
- The name of the wsdl
- That its a Remote Procedure Call
- That its encoded
- and a brief description
Then all we have to do is pass the server the HTTP POST request from the client:
$request = isSet($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$server->service($request);
And there you go!
Stay tuned next time for arrays of complex types!
Until then, just remember that I never said it work anyway!
Dk0
Comments
14 Responses to “Getting complex with PHP and NuSOAP (Part 1)”
Leave a Reply
I though Frank the rabbit was Donny Darko, so technically should he be in there twice?
Got it to work though! Will have a butchers at the code later!
No… Frank was Donnie’s sister’s boyfriend. If you watch the opening sequence his red sports car can be seen driving away from Donnie’s house!
Grandma Death and Roberta Sparrow are the same person though…
It took about 20 mins to write the code, but about two hours to write about the code… had to stop and break it into 3 posts!
Dk0
problems with leaving comments I already tried.
thanks sooo much for this. this is prob the best nusoap/soap demo ive seen and ive been searching for days now. this is great im slowly digesting it. many thanks.
Hi,
I went through the post and I found very useful. I need a help in php web service. I need to call my web service with login and password. its like calling of complex data types. Please help me how to do that.
It would be a great help for me.
Thanks
Venkat
Hi Venkat,
If you want to pass some kind of log in details to your web service there are a number ways to do it…
As SOAP uses HTTP POST data you can use an api key (or a user name and password) as a GET parameter in the URL…
Like: http://example.com/server.php?apikey=123456789
If you are using NuSOAP then you can still use the wsdl parameter like so:
http://example.com/server.php?apikey=123456789&wsdl
Of course you could also use HTTP Authentication but not necessarily all SOAP clients will work with this… The obvious option is to pass the credentials as parameters to the SOAP server’s methods but I always feel this looks ugly!
I hope that was some help!
Dk0
hey, i need help from the client side. i mean can you please write down the code for client that will show person’s information first name,last name etc
[…] Getting complex with PHP and NuSOAP […]
I have a question regarding a identifying the client by server. When I write a simple helloworld server and client codes all wsdl and other functions are working. But I want to identify the requesting client in server code and respond (To set in return value in hellowold function) that client address back to client. Please help me to solve this.
My nusoap.php in lib folder and all code in ‘http://localhost/services/’
Cleint code:
require_once(’./lib/nusoap.php’);
$client = new nusoap_client(’http://localhost/services/server.php?wsdl’, ‘true’);
echo $result = $client->call(’helloworld’);
Server code: (server.php)
require_once(’lib/nusoap.php’);
$server = new soap_server();
$server->configureWSDL(’hellowsdl’,'urn:hellowsdl’);
$server->register(’helloworld’,
array(’name’ = ‘xsd:string’),
array(’return’ = ‘xsd:string’),
‘urn:hellowsdl’,
‘urn:hellowsdl#hello’,
‘rpc’,
‘encoded’,
‘Says hello to the caller’
);
function helloworld()
{
return “Hi, “;
// I want to return requester(Client) address (Ip or url) here………………
// Return (This is your address………….)
}
// Use the request to (try to) invoke the service
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : ”;
$server->service($HTTP_RAW_POST_DATA);
Hi Samudaya,
The following code should do what you want:
function helloworld() {
return “Hi, “ . $_SERVER[”REMOTE_ADDR”];
}
Hi Darko,
Thanks lot. You solved a my two week stuck problem. Thanks again……….
Hi,
Any body knows the way of configure HTTPS on NuSaop. My WSDL is working correctly on https (That mean I can access the WSDL by browser through HTTPS). But how to configure in client end.
$client = new nusoap_client(’https://localhost/services/server.php?wsdl’, ‘true’);
What are the additional work for client connecting on top of https?
Thnaks………..
Hi,
Im trying to get an api key parameter value from nusoap server for authentication without any success please help me to get that.
http://example.com/server.php?apikey=123456789&wsdl
Hi Goodluck,
The API key will come through in the $_GET super global… just do the following inside you SOAP function:
$apiKey = isSet($_GET[’apikey’]) ? $_GET[’apikey’] : “”;