Powerful Web Services with PHP and SOAP

Started by Kalyan, Nov 27, 2008, 11:04 AM

Previous topic - Next topic

Kalyan

Powerful Web Services with PHP and SOAP

SOAP 101

SOAP is a protocol for applications and servers to communicate with each other. Its primary use in PHP is exposing Web services and building Web service clients. As a protocol, it can exchange messages over HTTP/HTTPS, which helps it get around firewalls that would block other protocols (eg, Remote Procedure Call). As an application layer protocol, SOAP is also entirely platform independent — your PHP Web application can talk to a Java database server, for example, as long as they both speak SOAP.

SOAP messages are simply XML with some custom namespaces, so they're fully machine-readable. Libraries are available for every major language, and working with SOAP Web services is quick, easy and fast.

SOAP for PHP

Today we're going to take a look at one of these libraries, NuSOAP. PHP has a few options for SOAP, including a PHP 5 extension, a PEAR package, and an independent (but very popular) library called NuSOAP. NuSOAP is the simplest way to get up and running with SOAP, but we could just as well have used PEAR::SOAP or the extension, and all three are interoperable — you can consume PEAR::SOAP exposed services with NuSOAP and vice versa, and scripts using either can happily run alongside each other.

Getting started with NuSOAP

To begin using NuSOAP, first head to the project page and download a copy of libraries — I'm using version 0.7.2. All examples should be forwards-compatible, but API changes happen, so check your library version if you encounter any errors. Drop the contents of the archive into a folder on your Web server — using /soap under my docroot. The latest version is compatible with the SOAP extension, but if you experience "class already declared" errors just disable the SOAP extension or rename the class in nusoap.php.

Your first SOAP request!

We'll start with the SOAP client. SOAP works with servers and clients; servers expose services and clients consume them. We'll start with a demo of a simple Web service that takes an argument and returns an array — but with the power of SOAP, we get that array data locally, almost as if the client was the server, and SOAP takes care of all the information in between.

Fire up your favourite text editor and type out the following:

<?php
include("lib/nusoap.php");
$soap = new soapclient("http://127.0.0.1/soap/hello_world_server.php");

$output = $soap->call("hello_world", array("name" => "Josh"));
print_r($output);

Save it as hello_world.php in the folder you created earlier. It can be anywhere, as long as the lib/nusoap.php reference still points to your NuSOAP library. Do the same for the server:

<?php
include("lib/nusoap.php");
$srv = new soap_server();
$srv->register("hello_world");
function hello_world($name)
{
    return array("data"=>"Hello World, {$name}!");
}
$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : "";
$srv->service($HTTP_RAW_POST_DATA);

Save this as hello_world_server.php in the same folder. If it can't be accessed at that URL in the client script (localhost/soap/...), change the reference in the client code as needed.

Then load up your Web browser, point it to the SOAP client — eg, http://localhost/soap/hello_world.php — and run the script. You should see the following:

Array
(
    [data] => Hello World, Josh!
)

That's perfectly normal print_r output — precisely what you would expect if you returned the array within the same PHP script. Except that our server script is separate, could be on a different server and could be running on a totally different platform — SOAP helps gets data from the server to the client as smoothly as possible.

The Server

Let's examine the server for a moment. Here's the code we used to build our server:

<?php
include("lib/nusoap.php");
$srv = new soap_server();

$srv->register("hello_world");
function hello_world($name)
{
    return array("data"=>"Hello World, {$name}!");
}

In this example, we first load up the NuSOAP library and register the service we want to expose, naming it "hello_world". We then define this service as a standard PHP function. At the moment, it does nothing but return a simple associative array, with the value containing an argument, $name. The client provides this argument from a totally separate PHP script and SOAP provides the glue to make sure it is passed in when the function is called.

HTTP is stateless, and our PHP script will be executed from the top down whenever a request is made, so each SOAP call (or other script execution) will be a new request. To check if we have a SOAP call (and what the SOAP client wants us to do), we have to scan each request for data. SOAP clients send POST requests, with XML data in the message body of the request, so we can fetch this raw POST data and pass it to the service() method of the soap_server class. Raw POST data is available in $HTTP_RAW_POST_DATA, but PHP won't set this unless it has a value, so we use a small hack to ensure it exists before passing it on to the SOAP server.

$HTTP_RAW_POST_DATA = isset($HTTP_RAW_POST_DATA) ? $HTTP_RAW_POST_DATA : '';
$srv->service($HTTP_RAW_POST_DATA);

We quickly get together the raw POST data, pass it to the SOAP library, and away we go.

The Client

The client uses the NuSOAP library, but only because we choose to — the server could use the PHP SOAP extension or PEAR::SOAP, and could be hosted anywhere. With the power of SOAP, we're going to take the PHP function on the server and talk to it through SOAP; we're also going to receive the result just like any other variable within our script. Have a look at the code for the client:

<?php
include("lib/nusoap.php");
$soap = new soapclient("http://127.0.0.1/soap/hello_world_server.php");

$output = $soap->call("hello_world", array("name" => "Josh"));
print_r($output);

The client is very basic — we first load up the library, then establish a connection to the SOAP server at the URL we've provided and call the "hello_world" service. For testing, we'll print_r the output. The second argument to the $soap->call() method is an array of parameters to be passed to the service. Notice we specify 'name' as the array key, the same as the $name argument on the server's function — this is not necessary as we aren't working with complex pre-defined services, however, it does hold importance when consuming slightly more elaborate SOAP services.

The service call returns a value which we then put into $output. If we check that print_r output earlier, it showed we had a perfectly good PHP associative array — [data] => Hello World, Josh! — just as our server's hello_world() function should have returned. In just a few lines of code, we've linked together two independent PHP scripts. Now your Web apps are really talking.

Behind the scenes: debugging SOAP

While you make high-level calls to the SOAP libraries, the NuSOAP library is actually busy generating and parsing XML request messages and passing them back and forth between server and client. You can easily examine the message body of your request and the server's response on the client side, using the request and response properties of the SOAP client class. These are invaluable in debugging, and will help you get a better understanding of SOAP internals, although you may never need it...

<?php
include("lib/nusoap.php");
$soap = new soapclient("http://127.0.0.1/soap/hello_world_server.php");

$output = $soap->call("hello_world", array("name" => "Josh"));
print_r($output);
echo '
'.htmlspecialchars($soap->request).'
';
echo '
'.htmlspecialchars($soap->response).'
';

This request will output something like the following:

POST /soap/hello_world_server.php HTTP/1.0
Host: 127.0.0.1
User-Agent: NuSOAP/0.7.2 (1.94)
Content-Type: text/xml; charset=ISO-8859-1
SOAPAction: ""
Content-Length: 511

<?xml version="1.0" encoding="ISO-8859-1"?><SOAP-ENV:Envelope ...

Notice we're making a direct POST request and passing all the XML through. In a HTML form request, that XML would be replaced with key=value&key=value pairs, which are then translated into elements of $_POST — this is why we have to request the raw POST data to check for a SOAP request. The actual XML schema for SOAP messages isn't important, as the libraries take care of it for us, but read up on the SOAP specifications if you want to take a closer look.

source : builderau

reign16


Kalyan

we can do some dynamic operations with powerful web integration tools and technologies... well, SOAP - Simple Object Access Protocol, is a protocol specification for exchanging structured information in the implementation of Web Services. and it relies on XML..............

PHP is an server side script for dynamic purpose...so, the both the process get together we have an powerfull web tool