This blog represents webservice implementation using PHP and SOAP for website developement. The ability to develop software and services for a wide range of platforms is a necessary skill, but not everyone uses the same language or platform and writing code to support them all is not feasible. What if there was a standard that allowed us to write code once and allow others to interact with it from their own software with ease. So luckily we have a protocol called “SOAP”.

SOAP allows us to build interoperable software and allows others to take advantage of our software over a network. It defines rules for sending and receiving Remote Procedure Calls (RPC) such as the structure of the request and responses. Therefore, SOAP is not tied to any specific operating system or programming language.

Here, in the first two part series of web services we will discuss about the SOAP specification and what is involved in creating SOAP messages. We’ll also demonstrate how to create a SOAP server and client using the excellent NuSOAP library to illustrate the flow of SOAP. In the second part we’ll talk about the importance of WSDL files, how you can easily generate them with NuSOAP as well, and how a client may use a WSDL file to better understand your web service.

The Structure of a SOAP Message

SOAP is based on XML so it is considered human read, but there is a specific schema that must be adhered to. Let’s first break down a SOAP message, stripping out all of its data, and just look at the specific elements that make up a SOAP message.

<?xml version=”1.0″?>
<soap:Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope
soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding“>
<soap:Header>
 …
</soap:Header>
<soap:Body>
 …
 <soap:Fault>
  …
 </soap:Fault>
</soap:Body>
</soap:Envelope>

This might look like just an ordinary XML file, but what makes it a SOAP message is the root element Envelope with the namespace soap as http://www.w3.org/2001/12/soap-envelope.

The soap:encodingStyleattribute determines the data types used in the file, but SOAP itself does not have a default encoding.

soap:Envelope is mandatory, but the next element, soap:Header, is optional and usually contains information relevant to authentication and session handling. The SOAP protocol doesn’t offer any built-in authentication, but allows developers to include it in this header tag.

Next there’s the required soap:Body element which contains the actual RPC message, including method names and, in the case of a response, the return values of the method. The soap:Fault element is optional; if present, it holds any error messages or status information for the SOAP message and must be a child element of soap:Body.

Let’s look at what SOAP request and response messages might look like. Let’s start with a request.

<?xml version=”1.0″?>
<soap:Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope
soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding“>
<soap:Body xmlns:m=”http://www.yourwebroot.com/stock“>
 <m:Ge Stock Price>
  <m:StockName>IBM</m:StockName>
 </m:Ge Stock Price>
</soap:Body>
</soap:Envelope>

Above is an example SOAP request message to obtain the stock price of a particular company. Inside soap:Body you’ll notice the GetStockPrice element which is specific to the application. It’s not a SOAP element, and it takes its name from the function on the server that will be called for this request.

The response message is similar to the request:

<?xml version=”1.0″?>
<soap:Envelope
xmlns:soap=”http://www.w3.org/2001/12/soap-envelope
soap:encodingStyle=”http://www.w3.org/2001/12/soap-encoding“>
<soap:Body xmlns:m=”http://www.yourwebroot.com/stock“>
 <m:Ge Stock Price Response>
  <m:Price>183.08</m:Price>
 </m:Ge Stock Price Response>
</soap:Body>
</soap:Envelope>

Building a SOAP Server

It couldn’t be easier to get NuSOAP up and running on your server; just visit sourceforge.net/projects/nusoap, download and unzip the package in your web root directory, and you’re done. To use the library just include the nusoap.php file in your code.

For the server, let’s say we’ve been given the task of building a service to provide a listing of products given a product category. The server should read in the category from a request, look up any products that match the category, and return the list to the user in a CSV format.

Create a file in your web root named productlist.php with the following code:

<?php
require_once “nusoap.php”;

function getProd($category) {
   if ($category == “books”) {
       return join(“,”, array(
           “The WordPress Anthology”,
           “PHP Master: Write Cutting Edge Code”,
           “Build Your Own Website the Right Way”));
}
else {
           return “No products listed under that category”;
}
}

$server = new soap_server();
$server->register(“getProd”);
$server->service($HTTP_RAW_POST_DATA);

?>

First, the nusoap.php file is included to take advantage of the NuSOAP library. Then, the getProd() function is defined. Afterward, a new instance of the soap_server class is instantiated, the getProd() function is registered with its register()method.

Now that we have a working server, let’s build a client to take advantage of it.

Building a SOAP Client

Create a file named productlistclient.php and use the code below:

<?php
require_once “nusoap.php”;
$client = new nusoap_client(“http://localhost/nusoap/productlist.php”);

$error = $client->getError();
if ($error) {
   echo “<h2>Constructor error</h2><pre>” . $error . “</pre>”;
}

$result = $client->call(“getProd”, array(“category” => “books”));

if ($client->fault) {
   echo “<h2>Fault</h2><pre>”;
   print_r($result);
   echo “</pre>”;
}
else {
   $error = $client->getError();
   if ($error) {
       echo “<h2>Error</h2><pre>” . $error . “</pre>”;
   }
   else {
       echo “<h2>Books</h2><pre>”;
       echo $result;
       echo “</pre>”;
   }
}

Once again we include nusoap.php with require_once and then create a new instance of nusoap_client. The constructor takes the location of the newly created SOAP server to connect to. The getError() method checks to see if the client was created correctly and the code displays an error message if it wasn’t.

The call() method generates and sends the SOAP request to call the method or function defined by the first argument. The second argument to call() is an associate array of arguments for the RPC. The fault property and getError()method are used to check for and display any errors. If no there are no errors, then the result of the function is outputted.

Now with both files in your web root directory, launch the client script(in my case http://localhost/nusoap/productlistclient.php) in your browser. You should see the following:

If you want to inspect the SOAP request and response messages for debug purposes, or if you just to pick them apart for fun, add these lines to the bottom of productlistclient.php:

echo “<h2>Request</h2>”;
echo “<pre>” . htmlspecialchars($client->request, ENT_QUOTES) . “</pre>”;
echo “<h2>Response</h2>”;
echo “<pre>” . htmlspecialchars($client->response, ENT_QUOTES) . “</pre>”;

The HTTP headers and XML content will now be appended to the output.

The Final Say :

In this blog, the first part of the series indicates that SOAP provides the ability to build interoperable software supporting a wide range of platforms and programming languages. We also learned about the different parts of a SOAP message and built your own SOAP server and client to demonstrate how SOAP works.

Next, we went a little deeper into the concept of SOAP rabbit hole and explained what a WSDL file is and how it can help you with the documentation and structure of your web service.

If you want to share your views, follow @letsnurture on Twitter, we will be happy to clear your doubts and answer your queries.

For any other information on mobile apps or web development and IoT solutions, please feel free to submit the inquiry form.

Thank you!!

Want to work with us? We're hiring!