Creating Web Services with PHP and SOAP, Part 1

As application engineers, the capacity to create programming and administrations for an extensive variety of stages is a fundamental aptitude, yet not everybody utilizes the same dialect or stage and composing code to help all of them is not possible. If there was a standard that permitted us to compose code once and permit others to associate with it from their own product no sweat. Well fortunately there is… and its name is SOAP. (Cleanser used to be an acronym which remained for Simple Object Access Protocol, however as of variant 1.2 the convention goes just by the name SOAP.)

Cleanser permits you to assemble interoperable programming and permits others to exploit your product over a system. It characterizes guidelines for sending and getting Remote Procedure Calls (RPC, for example, the structure of the appeal and reactions. Subsequently, SOAP is not fixed to any particular working framework or programming dialect. As that matters is somebody can figure and parse a SOAP message in their picked dialect

In this first of a two section arrangement on web administrations I’ll discuss the SOAP particular and what is included in making SOAP messages. I’ll additionally exhibit how to make a SOAP server and customer utilizing the fantastic Nusoap library to outline the stream of SOAP. In the second part I’ll discuss the essentialness of WSDL records, how you can without much of a stretch create them with Nusoap too, and how a customer may utilize a WSDL document to better comprehend your web administration.

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?xml version="1.0"?>
<soap:Envelope
 <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:encodingStyle attribute 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.

Now that you understand the basics of what makes up a SOAP message, let’s look at what SOAP request and response messages might look like. Let’s start with a request.

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
<soap:Envelope
 <soap:Body xmlns:m="http://www.yourwebroot.com/stock">
  <m:GetStockPrice>
   <m:StockName>IBM</m:StockName>
  </m:GetStockPrice>
 </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. StockName is also specific to the application and is an argument for the function.

The response message is similar to the request:

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0"?>
<soap:Envelope
 <soap:Body xmlns:m="http://www.yourwebroot.com/stock">
  <m:GetStockPriceResponse>
   <m:Price>183.08</m:Price>
  </m:GetStockPriceResponse>
 </soap:Body>
</soap:Envelope>

Inside the soap:Body element there is a GetStockPriceResponse element with a Price child that contains the return data. As you would guess, both GetStockPriceResponse and Price are specific to this application.

Now that you’ve seen an example request and response and understand the structure of a SOAP message, let’s install NuSOAP and build a SOAP client and server to demonstrate generating such messages.

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 direoctry, 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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?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.

This is really all that’s needed to create your own SOAP server – simple, isn’t it? In a real-world scenario you would probably look up the list of books from a database, but since I want to focus on SOAP, I’ve mocked getProd() to return a hard-coded list of titles.

If you want to include more functionality in the sever you only need to define the additional functions (or even methods in classes) and register each one as you did above.

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?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 casehttp://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:

1
2
3
4
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.

 

Advertisements