Creating a SOAP Server

Creating a SOAP server with the native SOAP extension is easier than you think. Although several server-specific methods are provided with the SOAP extension, only three methods are required to create a complete WSDL-enabled server. This section introduces these and other methods, guiding you through the process of creating a functional SOAP server as the section progresses. The section "SOAP Client and Server Interaction" offers a complete working example of the interaction between a WSDL-enabled client and server created using this extension. To illustrate this, the examples in the remainder of this chapter refer to Listing 20-6, which offers a sample WSDL file. Directly following the listing, a few important SOAP configuration directives are introduced that you need to keep in mind when building SOAP services using this extension.

Listing 20-6. A Sample WSDL File (boxing. wsdl)

<?xml version="1.0" ?> <definitions name="boxing"

targetNamespace="http://www.wjgilmore.com/boxing" xmlns:tns="http://www.wjgilmore.com/boxing" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns="http://schemas.xmlsoap.org/wsdl/">

<message name="getQuoteRequest"> <part name="boxer" type="xsd:string" /> </message>

<message name="getQuoteResponse">

<part name="return" type="xsd:string" /> </message>

<portType name="QuotePortType"> <operation name="getQuote"> <input message="tns:getQuoteRequest" /> <output message="tns:getQuoteResponse" /> </operation> </portType>

<binding name="QuoteBinding" type="tns:QuotePortType"> <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" /> <operation name="getQuote"> <soap:operation soapAction="" /> <input> <soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> </input> <output> <soap:body use="encoded"

encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" /> </output> </operation> </binding>

<service name="boxing"> <documentation>Returns quote from famous pugilists</documentation> <port name="QuotePort" binding="tns:QuoteBinding"> <soap:address location="http://www.wjgilmore.com/boxingserver.php" /> </port> </service> </definitions>

The SoapServer() constructor instantiates a new instance of the SoapServer class in WSDL or non-WSDL mode. Its prototype looks like this:

object SoapServer->SoapServer(mixed wsdl [, array options])

If you require WSDL mode, you need to assign the wsdl parameter the WSDL file's location, or else set it to NULL. The optional options parameter is an array used to set the following options:

actor: Identifies the SOAP server as an actor, defining its URI.

encoding: Sets the character encoding.

soap_version: Determines the supported SOAP version and must be set with the syntax SOAP_x_y, where x is an integer specifying the major version number, andy is an integer specifying the corresponding minor version number. For example, SOAP version 1.2 would be assigned as SOAP_1_2.

The following example creates a SoapServer object referencing the boxing.wsdl file:

$soapserver = new SoapServer("boxing.wsdl");

If the WSDL file resides on another server, you can reference it using a valid URI:

$soapserver = new SoapServer("http://www.example.com/boxing.wsdl");

Next, you need to export at least one function, a task accomplished using the addFunction() method, introduced next.

■Note If you're interested in exposing all methods in a class through the SOAP server, use the method setClass(), introduced later in this section.

Adding a Server Function

You can make a function available to clients by exporting it using the addFunction() method. In the WSDL file, there is only one function to implement, getQuote(). It takes $boxer as a lone parameter and returns a string. Let's create this function and expose it to connecting clients:

<?php function getQuote($boxer) { if ($boxer == "Tyson") {

$quote = "My main objective is to be professional but to kill him. (2002)"; } elseif ($boxer == "Ali") {

$quote = "I am the greatest. (1962)"; } elseif ($boxer == "Foreman") {

$quote = "Generally when there's a lot of smoke, there's just a whole lot more smoke. (1995)";

return $quote;

$soapserver = new SoapServer("boxing.wsdl");

$soapserver->addFunction("getQuote");

When two or more functions are defined in the WSDL file, you can choose which ones are to be exported by passing them in as an array, like so:

$soapserver->addFunction(array("getQuote","someOtherFunction");

Alternatively, if you would like to export all functions defined in the scope of the SOAP server, you can pass in the constant SOAP_FUNCTIONS_ALL, like so:

$soapserver->addFunction(array(SOAP_FUNCTIONS_ALL);

It's important to understand that exporting the functions is not all that you need to do to produce a valid SOAP server. You also need to properly process incoming SOAP requests, a task handled for you via the method handle(). This method is introduced next.

Adding Class Methods

Although the addFunction() method works fine for adding functions, what if you want to add class methods? This task is accomplished with the setClass() method. Its prototype follows:

void SoapServer->setClass(string class_name [, mixed args])

The class_name parameter specifies the name of the class, and the optional args parameter specifies any arguments that will be passed to a class constructor. Let's create a class for the boxing quote service and export its methods using setClass():

<?php class boxingQuotes {

function getQuote($boxer) { if ($boxer == "Tyson") {

$quote = "My main objective is to be professional but to kill him. (2002)"; } elseif ($boxer == "Ali") {

$quote = "I am the greatest. (1962)"; } elseif ($boxer == "Foreman") {

$quote = "Generally when there's a lot of smoke, there's just a whole lot more smoke. (1995)";

return $quote;

$soapserver = new SoapServer("boxing.wsdl");

$soapserver->setClass("boxingQuotes"); $soapserver->handle();

The decision to use setClass() instead of addFunction() is irrelevant to any requesting clients. Directing Requests to the SOAP Server

Incoming SOAP requests are received by way of either the input parameter soap_request or the PHP global $HTTP_RAW_POST_DATA. Either way, the method handle() will automatically direct the request to the SOAP server for you. Its prototype follows:

void SoapServer->handle([string soap_request])

It's the last method executed in the server code. You call it like this: $soapserver->handle();

Persisting Objects Across a Session

One really cool feature of the SOAP extension is the ability to persist objects across a session. This is accomplished with the setPersistence() method. Its prototype follows:

void SoapServer->setPersistence(int mode)

This method only works in conjunction with setClass(). Two modes are accepted:

SOAP_PERSISTENCE_REQUEST: This mode specifies that PHP's session-handling feature should be used to persist the object.

SOAP_PERSISTENCE_SESSION: This mode specifies that the object is destroyed at the end of the request.

Was this article helpful?

0 0

Post a comment