This document describes how to obtain and install NuSOAP, and then provides some examples to illustrate the functions of NuSOAP. This is not a comprehensive introduction to NuSOAP, but hopefully some PHP developers can have a good introduction.
NuSOAP is a set of PHP classes that allow developers to create and use SOAP web services. It does not require any PHP extensions to be installed. It was developed on December 3, 2004, and the current version is NuSOAP (0.6.7). Supporting the SOAP 1.1 specification, it can produce and use WSDL 1.1, and also supports rpc/encoded and document/literal services. However, it is important to note that NuSOAP does not provide a complete implementation like .NET and Apache Axis.
Hello, World
I'll start with the "Hello, World" example and write basic NuSOAP client and server code.
Let's start with the server side first, because without the server side, it makes no sense to have the client side. We're going to write a SOAP method named Hello that takes a single parameter and returns a string, and hopefully the comments in the code will provide useful instructions.
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register('hello');
// Define the method as a PHP function
function hello($name) {
return 'Hello, ' . $name;
}
// 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);
?>
The following is the client code. There are some important things to note: First, when creating the instance soapclient, you need to specify a service URL as a parameter. In this example, helloworld.php is accessed from http://localhost/phphack of. Of course, the services you want to use are placed in different URLs; secondly, when calling service, the first parameter is the name of the service, which must match a valid method name (some servers are case-sensitive). In this example, it must match the method already registered in helloworld.php. Finally, the second parameter is an array that will be passed to the SOAP service method as a parameter. Since the hello method in helloworld.php has only one parameter, the array has only one element.
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Display the result
print_r($result);
?>
Debugging
When programming, you need to debug whenever something goes wrong. NuSOAP provides a set of tools to help you do this. The information you need to check when debugging NuSOAP is the request information sent and the corresponding information returned. NuSOAP's client class allows you to view this information through its two members. For example, here is a modified version of helloworldclient.php that shows the request and response. In the next section I'll review the request and response information displayed in the client code.
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Display the result
print_r($result);
// Display the request and response
echo '<h2>Request</h2>';
echo '<pre>' . htmlspecialchars($client->request, ENT_QUOTES) . '</pre>';
echo '<h2>Response</h2>';
echo '<pre>' . htmlspecialchars($client->response, ENT_QUOTES) . '</pre>';
?>
NuSOAP also provides a method to view debugging information through logs using its classes. Adding the following code will display lengthy debugging information. Unfortunately the description of the output must be left to the reader.
// Display the debug messages
echo '<h2>Debug</h2>';
echo '<pre>' . htmlspecialchars($client->debug_str, ENT_QUOTES) . '</pre>';
The server can provide similar debugging information. Interestingly, these debugging information are in xml at the end of the corresponding SOAP The format is displayed so it can be viewed in the client. Server-side debugging looks like this:
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Enable debugging *before* creating server instance
$debug = 1;
// Create the server instance
$server = new soap_server;
// Register the method to expose
$server->register('hello');
// Define the method as a PHP function
function hello($name) {
return 'Hello, ' . $name;
}
// 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);
?>
The third method of debugging is not really debugging, it is good programming practice. The above example does not do error checking when calling SOAP. A more robust client would look like this:
<?php
// Pull in the NuSOAP code
require_once('nusoap.php');
// Create the client instance
$client = new soapclient('http://localhost/phphack/helloworld.php');
// Check for an error
$err = $client->getError();
if ($err) {
// Display the error
echo '<p><b>Constructor error: ' . $err . '</b></p>';
// At this point, you know the call that follows will fail
}
// Call the SOAP method
$result = $client->call('hello', array('name' => 'Scott'));
// Check for a fault
if ($client->fault) {
echo '<p><b>Fault: ';
print_r($result);
echo '</b></p>';
} else {
// Check for errors
$err = $client->getError();
if ($err) {
// Display the error
echo '<p><b>Error: ' . $err . '</b></p>';
} else {
// Display the result
print_r($result);
}
}
?>
In order to test the code, you need to cause an error to occur, for example, change the called method name hello to goodbye.
Request and Response
I've shown in the example above how easy it is to display SOAP request and response information, here is the request information for hello2client.php:
POST /phphack/helloworld2.php HTTP/1.0
Host: localhost
User-Agent: NuSOAP/0.6.8 (1.81)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: ""
Content-Length: 538
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle=" http://schemas.xmlsoap.org/soap/encoding/ "
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:si=" http://soapinterop.org/xsd ">
<SOAP-ENV:Body>
<ns1:hello xmlns:ns1=" http://testuri.org ">
<name xsi:type="xsd:string">Scott</name>
</ns1:hello>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
In the HTTP headers, you will see that SOAPAction is an empty string, which is its default value. Your service method can set the value of the SOAPAction, and your client code can call the method specifying the SOAPAction as a parameter.
In the XML payload, you can see that NuSOAP uses the well-known ISO-8859-1 encoding as Latin-1. In order to specify a different encoding, you can set the soap_defencoding attribute on the client soapclient instance. It is of course the programmer's responsibility to encode parameter data using the specified encoding. Fortunately, PHP provides many functions to encode and decode the most common encoding data in SOAP, such as UTF-8.
Another thing to note is that the element specifies the method to be called. The element named hello is placed under the domain name http://tempuri.org . Specifying the real domain name is a best practice and is also very common for many services. It is necessary. A future document is shown here:
The SOAP service responds like this:
HTTP/1.1 200 OK
Server: Microsoft-IIS/5.0
Date: Wed, 03 Nov 2004 21:32:34 GMT
X-Powered-By: ASP.NET
X-Powered-By: PHP/4.3.4
Server: NuSOAP Server v0.6.8
X-SOAP-Server: NuSOAP/0.6.8 (1.81)
Content-Type: text/xml; charset=ISO-8859-1
Content-Length: 556
<?xml version="1.0" encoding="ISO-8859-1"?>
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle=" http://schemas.xmlsoap.org/soap/encoding/ "
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:si=" http://soapinterop.org/xsd ">
<SOAP-ENV:Body>
<ns1:helloResponse xmlns:ns1=" http://tempuri.org ">
<return xsi:type="xsd:string">Hello, Scott</return>
</helloResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>