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:

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:

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

Continued in Part 2

Comments

14 Responses to “Getting complex with PHP and NuSOAP (Part 1)”

  1. Rob on September 25th, 2006 4:35 pm

    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!

  2. Darko on September 25th, 2006 4:43 pm

    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

  3. SDavis on September 24th, 2007 11:39 pm

    problems with leaving comments I already tried.

  4. adom on August 5th, 2008 9:31 am

    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.

  5. venkat on November 7th, 2008 2:25 pm

    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

  6. Darko on November 7th, 2008 2:42 pm

    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

  7. cse031sust02 on December 18th, 2008 11:13 am

    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

  8. nuSOAP Documentation Repository « A world of LDAP and RADIUS on February 20th, 2009 4:29 pm

    […] Getting complex with PHP and NuSOAP […]

  9. Samudaya on April 21st, 2009 1:19 pm

    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);

  10. Darko on April 21st, 2009 4:07 pm

    Hi Samudaya,

    The following code should do what you want:

    function helloworld() {
    return “Hi, “ . $_SERVER[”REMOTE_ADDR”];
    }

  11. Samudaya on April 27th, 2009 7:15 am

    Hi Darko,
    Thanks lot. You solved a my two week stuck problem. Thanks again……….

  12. Samudaya on May 12th, 2009 6:15 am

    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………..

  13. Goodluck Msangi on February 10th, 2010 12:15 pm

    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

  14. Darko on February 10th, 2010 12:33 pm

    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’] : “”;

Leave a Reply