Overview
The purpose of this tutorial is to discuss in detail how to create a NuSOAP/PHP/SOAP web service using Adobe Dreamweaver CS4. This tutorial is ideal for beginners and experts alike.
I wrote an article some time ago discussing how to develop SOAP/PHP web services using NuSOAP. This was a very general tutorial and didn’t go into much detail in relation to actually writing your first web service. This tutorial uses some code from Scott Nichol’s website.
Prerequisites
Introduction
A web service provides us with a means of communication between a client/server configuration. A web service is literally just a set of Application Programming Interfaces (APIs) that we can use to exchange data (usually over the web). SOAP [XML derivative] is the protocol typically used to provide standardization across all platforms and technologies.
NuSOAP is a third party plug-in that brings this functionality to PHP with all of the leg work done for us.
Introduction to NuSOAP
NuSOAP provides all the code pre-written that we need to create our web service.
NuSOAP supports the following features:
- Runs independently. Does not require any additional plug-ins or server reconfigurations
- SOAP version 1.1
- WSDL (Web Service Descriptor Language) 1.1
- HTTP
- Complex Types
Make sure you have downloaded and extracted NuSOAP and are ready to get into it.
Hello, World! Example Web Service
The quickest, easiest way to learn is by doing, so let's get straight into it.
require_once("nuSOAP/lib/nusoap.php");
$server = new soap_server();
$namespace = "http://localhost/nusoaphelloworld/index.php";
$server->wsdl->schemaTargetNamespace = $namespace;
$server->configureWSDL("HelloWorld");
$server->register('HelloWorld');
function HelloWorld()
{
return "Hello, World!";
}
$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
$server->service($POST_DATA);
exit();
This is very similar to the original code sample I wrote, but it's important to lay the foundations. Let's see what’s going on here:
- Create a
soap_server
- Define the namespace of the web server and configure our WSDL document
- Register our
HelloWorld
method - Write our actual method
- Output raw data
This web service exposes a single method, ‘HelloWorld
’, which itself outputs a “Hello, World!
” string
when raised.
NuSOAP generates a WSDL document that looks exactly like this:
<definitions xmlns:soap-env=http://schemas.xmlsoap.org/soap/envelope/
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:soap-enc=http://schemas.xmlsoap.org/soap/encoding/
xmlns:tns=http://localhost/soap/HelloWorld
xmlns:soap=http://schemas.xmlsoap.org/wsdl/soap/
xmlns:wsdl=http://schemas.xmlsoap.org/wsdl/
xmlns=http://schemas.xmlsoap.org/wsdl/
targetnamespace="http://localhost/soap/HelloWorld">
<types>
<xsd:schema targetnamespace="http://localhost/soap/HelloWorld">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/">
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/">
</xsd:import></xsd:import></xsd:schema>
</types>
<message name="HelloWorldRequest">
<message name="HelloWorldResponse">
<porttype name="HelloWorldPortType">
<operation name="HelloWorld">
<input message="tns:HelloWorldRequest" />
<output message="tns:HelloWorldResponse">
</output></operation>
</porttype>
<binding name="HelloWorldBinding" type="tns:HelloWorldPortType">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http">
<operation name="HelloWorld">
<soap:operation soapaction="http://localhost/nusoaphelloworld/index.php/HelloWorld">
<input /><soap:body use="encoded"
encodingstyle="http://schemas.xmlsoap.org/soap/encoding/">
<output><soap:body use="encoded"
encodingstyle="http://schemas.xmlsoap.org/soap/encoding/" /></output>
</soap:body></soap:operation></operation>
</soap:binding></binding>
<service name="HelloWorld">
<port name="HelloWorldPort" binding="tns:HelloWorldBinding">
<soap:address location="http://localhost/nusoaphelloworld/index.php">
</soap:address></port>
</service>
</message></message></definitions>
There is an awful lot going on here, and thankfully we do not have to concern ourselves with most of it. When using consumption tools, such as Visual C# for example, the interpreter will read the WSDL document, interpret what methods are being exposed, their data types, complex types, names and everything else automatically so we literally have to do nothing.
You can easily view the WSDL document by typing ?WSDL at the end of your PHP file name in the address bar. (e.g. http://localhost/nusoaphelloworld/index.php?WSDL)
Less Trivial Example
Ok so the above example is simple, but there is more you can do here. You can actually pass values to your methods to make them more useful. So let’s say for example that you wanted to pass a persons ‘name’ to your function, and then output it to screen. This is easily achievable by adding parameters to your functions. Example:
require_once("nuSOAP/lib/nusoap.php");
$namespace = "http://localhost/nusoaphelloworld/index.php";
$server = new soap_server();
$server->configureWSDL("HelloExample");
$server->wsdl->schemaTargetNamespace = $namespace;
$server->register(
'HelloWorld',
array('name'=>'xsd:string'),
array('return'=>'xsd:string'),
$namespace,
false,
'rpc',
'encoded',
'Simple Hello World Method');
$server->wsdl->addComplexType('MyComplexType','complexType','struct','all','',
array( 'ID' => array('name' => 'ID','type' => 'xsd:int'),
'YourName' => array('name' => 'YourName','type' => 'xsd:string')));
$server->register(
'HelloComplexWorld',
array('name'=>'tns:MyComplexType'),
array('return'=>'tns:MyComplexType'),
$namespace,
false,
'rpc',
'encoded',
'Complex Hello World Method');
function HelloWorld($name)
{
return "Hello " . $name;
}
function HelloComplexWorld($mycomplextype)
{
return $mycomplextype;
}
$POST_DATA = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : '';
$server->service($POST_DATA);
exit();
Notice that when we register our method, we can define some additional parameters that provide more information. We can stipulate a list of parameters (as an array), the return data, and even the documentation text to apply.
If you look at your web service in your web browser, you will see something like this:
Now that we understand how to pass simple data types (string
s, integer
s, etc.) to our web service and also how to return simple data types, what next? Well, SOAP/XML web services all use to define complex custom data types to return data in a more useful, structured manner.
Complex Types
Complex types all use to create our own, customized data types for easier, more structured data handling. Simple types (such as string
and integer
) only have limited usage. What if we could create our own types? You can do this easily and quickly using NuSOAP;
Create your complex type;
Use NuSOAP’s built in AddComplexType
method to create your own complex type:
$server->wsdl->addComplexType('MyComplexType','complexType','struct','all','',
array( 'ID' => array('name' => 'ID','type' => 'xsd:int'),
'YourName' => array('name' => 'YourName','type' => 'xsd:string')));
The method is very simple. Give your complex type a name (MyComplexType
), tell your WSDL document that it's a complex type (struct
) and then specify the parameters.
In the above example, we have two properties in our type; ID
(Integer
), and YourName
(string
).
We must then register our method with the complex type specified as the data type instead of a simple type. (We use tns instead of xsd here.)
$server->register(
'HelloComplexWorld',
array('name'=>'tns:MyComplexType'),
array('return'=>'tns:MyComplexType'),
$namespace,
false,
'rpc',
'encoded',
'Complex Hello World Method');
In this case, we have said that we want our parameter to be of type MyComplexType
and also to return the MyComplexType
data type.
Consumption
You can consume (use, implement) web services from any platform/language that supports them. This example uses Visual C# 2010 on Microsoft Windows Vista.
Note: This tutorial uses Visual C# 2010, but also uses .NET Framework 2.0.
Read the full tutorial on Visual C# consumption here.
Your code will look something like this:
var ex = new HelloExample();
string simpleResult = ex.HelloWorld("Jon");
var myComplexType = new MyComplexType {ID = 1, YourName = "Jon"};
MyComplexType complexResult = ex.HelloComplexWorld(myComplexType);
Console.WriteLine("Simple: {0}", simpleResult);
Console.WriteLine("Complex: {0}", complexResult.YourName);
textBox1.Text = simpleResult;
textBox2.Text = complexResult.YourName;
You can find this code and more in the demo app.
Live Demo
The web service discussed in this tutorial is live and can be view/consumed at any time:
History
- 27th December, 2010: Initial post