SOAP – Server

SOAP is the acronym for Simple Object Access Protocol, it uses the web and XML for a client to find out what functions are available on a server using the WSDL (Web Server Description Language) (this is also in XML format) and once the client knows what functions are available and also what parameters can be passed, the client is then able to call the function and gain the response from the server.

I am using the Zend Framework to auto generate the WSDL file since there does not appear to be at present a function within the PHP standard framework to create one, I have included below how to install the Zend framework. Once you have installed the framework you need to either alter the php.ini file to tell it where the framework is or within the .php file for your server include details on where the framework is within that and include the relevant files.

Below I have told the php runtime within the .php file where the zend library framework is by using ini_setup include path settings.

/* setup the including path for the zend library framework */
ini_set('include_path', '/usr/share/php/libzend-framework-php/');
/* and include the zend soap files */
require_once 'Zend/Soap/AutoDiscover.php';
require_once "Zend/Soap/Server.php";

with including the auto discover (the WSDL generator part of the zend framework that we are wanting) and the server php files.

For the auto discover to work you need to use the php doc notation so that the WSDL can be generated correctly, so for example if you was using a function that was taking in a string and returning a string as in the main example below, you would use something like this (where the php doc is /** start)

  /**
   * @param string $quote
   * @return string
  */
  function getQuote($quote) {

To generate WSDL file I am using the parameter within the URL (?wsdl) and thus if that is present auto generate the WSDL file else act as the server, so

/* if the client is requesting the WSDL file (the web service definition language) */
if(isset($_GET['wsdl'])) {
   // use the zend soap autodiscover function to create the wsdl file from using the phpdoc info from the class QuoteOfTheDay */
    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('QuoteOfTheDay');
    $autodiscover->handle();

with using the Zend_Soap_AutoDiscover class and then setting up the class that you want to expose to the WSDL generator / server and then output (handle) the WSDL request.

Here is the full code

<?php
 
/* setup the including path for the zend library framework */
ini_set('include_path', '/usr/share/php/libzend-framework-php/');
/* and include the zend soap files */
require_once 'Zend/Soap/AutoDiscover.php';
require_once "Zend/Soap/Server.php";
 
/* this is the class to be *expose* to the SOAP interface */
class QuoteOfTheDay {
 
  /* the quotes to be used from within the function getQuote */
  private $quotes = array("monday" => "Monday's child is fair of face", "tuesday"=>"Tuesday's child is full of grace","wednesday" =>"Wednesday's child is full of woe",
  "thursday" =>"Thursday's child has far to go", "friday" => "Friday's child is loving and giving", "saturday" =>"Saturday's child works hard for a living",
  "sunday" =>"But the child who is born on the Sabbath Day - Is bonny and blithe and good and gay");  
 
/* you have to use the phpDoc format for the zend soap auto discover to pick up the parameters and return types */
  /**
   * @param string $quote
   * @return string
  */
  function getQuote($quote) {
    /* just encase the string is in uppercase*/
    $symbol = strtolower($quote);
    /* if there is a quote for the day requested */
    if (isset($this->quotes[$quote])) {
      return $this->quotes[$quote];
    } else {
      /* else error */
      throw new SoapFault("Server","Unknown Symbol '$quote'.");
    }
  }
}
 
/* if the client is requesting the WSDL file (the web service definition language) */
if(isset($_GET['wsdl'])) {
   // use the zend soap autodiscover function to create the wsdl file from using the phpdoc info from the class QuoteOfTheDay */
    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('QuoteOfTheDay');
    $autodiscover->handle();
} else {
  // otherwise I am the server in question, setup a new soap server with the a handle on the class QuoteOfTheDay 
    $soap = new Zend_Soap_Server("http://localhost/projects/webservice/zend_soap_server.php?wsdl"); // this current file here
    $soap->setClass('QuoteOfTheDay');
    $soap->handle();
}
?>

Save that as the zend_soap_server.php within your local PHP web serving directory you need to have the zend framework installed, below may help (within the php.ini there will either a extension list normally within a Windows setup)

in Linux (Ubuntu/Kubuntu etc) I installed the zend frame work for php by

aptitude install libzend-framework-php

or on windows this URL may be of use ? installing zend framework on windows

This is the output of the XML for the WSDL generation, it would be the output of a URL similar to http://localhost/zend_soap_server.php?wsdl

<definitions name="QuoteOfTheDay" targetNamespace="http://localhost/projects/webservice/zend_soap_server.php">
-
<types>
<xsd:schema targetNamespace="http://localhost/projects/webservice/zend_soap_server.php"/>
</types>
-
<portType name="QuoteOfTheDayPort">
-
<operation name="getQuote">
<documentation>@param string $quote</documentation>
<input message="tns:getQuoteIn"/>
<output message="tns:getQuoteOut"/>
</operation>
</portType>
-
<binding name="QuoteOfTheDayBinding" type="tns:QuoteOfTheDayPort">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
-
<operation name="getQuote">
<soap:operation soapAction="http://localhost/projects/webservice/zend_soap_server.php#getQuote"/>
-
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/projects/webservice/zend_soap_server.php"/>
</input>
-
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/projects/webservice/zend_soap_server.php"/>
</output>
</operation>
</binding>
-
<service name="QuoteOfTheDayService">
-
<port name="QuoteOfTheDayPort" binding="tns:QuoteOfTheDayBinding">
<soap:address location="http://localhost/projects/webservice/zend_soap_server.php"/>
</port>
</service>
-
<message name="getQuoteIn">
<part name="quote" type="xsd:string"/>
</message>
-
<message name="getQuoteOut">
<part name="return" type="xsd:string"/>
</message>
</definitions>