SOAP Servers and Web Services

In this conclusion to a five-part article series on Web Services, you’ll learn how to create a SOAP server, add server functions, and more. This article is excerpted from chapter 20 of the book Beginning PHP and Oracle: From Novice to Professional, written by W. Jason Gilmore and Bob Bryla (Apress; ISBN: 1590597702).

Retrieving the Exposed Methods

The __getFunctions() method returns an array consisting of all methods exposed by the service referenced by the SoapClient object. The prototype looks like this:

array SoapClient->__getFunctions()

The following example establishes a connection to the boxing quotation SOAP server and retrieves a list of available methods:

<?php
  
$ws = http://www.wjgilmore.com/boxing.wsdl;
   $client = new SoapClient($ws);
   var_dump($client->__getFunctions());
?>

This example returns the following (formatted for readability):

array(1) {
  
[0]=> string(30) "string getQuote(string $boxer)"
}

One method is exposed, getQuote() , and it requires that you pass in the name of a boxer, returning a string (presumably a quotation).

In the following sections you’ll learn how the boxing quotation SOAP server was created and see it in action.

{mospagebreak title=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, and y  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.

 


 

{mospagebreak title=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)";
       
} else {
           
$quote = "Sorry, $boxer was not found.";
       
}
       
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.

{mospagebreak title=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)";
           
} else {
               
$quote = "Sorry, $boxer was not found.";
           
}
           
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.

{mospagebreak title=SOAP Client and Server Interaction}

Now that you’re familiar with the basic premises of using this extension to create both SOAP clients and servers, this section presents an example that simultaneously demonstrates both concepts. This SOAP service retrieves a famous quote from a particular boxer, and that boxer’s last name is requested using the exposed getQuote() method. It’s based on the boxing.wsdl file shown earlier in Listing 20-5. Let’s start with the server.

Creating the Boxing Server

The boxing server is simple but practical. Extending this to connect to a database server would be a trivial affair. Let’s consider the code:

<?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)";
           
} else {
               
$quote = "Sorry, $boxer was not found.";
           
}
           
return $quote;
        }
    }

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

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

The client, introduced next, will consume this service.

Executing the Boxing Client

The boxing client consists of just two lines, the first instantiating the WSDL-enabled SoapClient() class, and the second executing the exposed method getQuote(), passing in the parameter "Ali":

<?php
   
$client = new SoapClient("boxing.wsdl");
   
echo $client->getQuote("Ali");
?>

Executing the client produces the following output:

——————————————–
I am the greatest. (1962)
——————————————–

Summary

The promise of Web Services and other XML-based technologies has generated an incredible amount of work in this area, with progress regarding specifications and the announcement of new products and projects happening all the time. No doubt such efforts will continue, given the incredible potential that this concentration of technologies has to offer.

In the next chapter, you’ll turn your attention to the security-minded strategies that developers should always keep at the forefront of their development processes.  

[gp-comments width="770" linklove="off" ]

chat sex hikayeleri Ensest hikaye