Jump to content

SOAP - WSDL - client and server

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
2 replies to this topic

#1
genux

genux

    Learning Programmer

  • Members
  • PipPipPip
  • 80 posts
SOAP is a Simple Object Access Protocol and it allows for a server to "talk" to a client over the internet once the client knows what functions (and the parameters attached to those functions) are present, this is exposed via the WSDL (Web Service Description Language). In PHP a way to generate the WSDL file on the file it is possible to do this with the Zend framework. (you can of course not use a WSDL and specify all of the function names and parameters by hand in the client, but I do not find that the best way of doing that unless you want to hide the server from other clients ?)

Once you have installed the Zend framework, you can then reference it either within the php.ini file or within the .php file that you are running as the server for just that web page as such, I am using the latter in this instance, so

/* 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";
the above tells the php compiler where the zend library framework is and also what files I want to include from that base directory.

The Server and WSDL file

To generate the WSDL on the fly there is a auto discover function, it also helps to have the php doc notation to help generate this WSDL file, all you need is the /** e.g.

  /**
   * @param string $quote
   * @return string
  */
  function getQuote($quote) {
and then to generate a WSDL file on the fly, you first call the auto discovery service and then set the class that you want to have "exposed" via the WSDL file and then call the handler to generate the output as below

    $autodiscover = new Zend_Soap_AutoDiscover();
    $autodiscover->setClass('QuoteOfTheDay');
    $autodiscover->handle();
Here is the full server code that will either generate a WSDL file or act as the SOAP server, (if you pass in as a parameter to the URL ?wsdl then the WSDL file is generated), if you save this as zend_soap_server_codecall.php

<?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 {

/* 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) {
      return $quote . " : Codecall was here!!";
  }
}

/* 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/zend_soap_server_codecall.php?wsdl"); // this current file here
    $soap->setClass('QuoteOfTheDay');
    $soap->handle();
}
?>
This is what the WSDL *should* look like

<definitions name="QuoteOfTheDay" targetNamespace="http://localhost/projects/webservice/zend_soap_server_codecall.php">
−
<types>
<xsd:schema targetNamespace="http://localhost/projects/webservice/zend_soap_server_codecall.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_codecall.php#getQuote"/>
−
<input>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/projects/webservice/zend_soap_server_codecall.php"/>
</input>
−
<output>
<soap:body use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost/projects/webservice/zend_soap_server_codecall.php"/>
</output>
</operation>
</binding>
−
<service name="QuoteOfTheDayService">
−
<port name="QuoteOfTheDayPort" binding="tns:QuoteOfTheDayBinding">
<soap:address location="http://localhost/projects/webservice/zend_soap_server_codecall.php"/>
</port>
</service>
−
<message name="getQuoteIn">
<part name="quote" type="xsd:string"/>
</message>
−
<message name="getQuoteOut">
<part name="return" type="xsd:string"/>
</message>
</definitions>
The Client

What the SOAP client does is connects to the servers WSDL file and finds out what functions (and there parameters/return values).

To connect to the server

  $client = new  SoapClient("http://localhost/projects/webservice/zend_soap_server_codecall.php?wsdl")
in this instance I am passing in a array of options to the SoapClient

    array(
      "trace"      => 1,        // enable trace to view what is  happening
      "exceptions" => 0,        // disable exceptions
      "cache_wsdl" => 0)         // disable any caching on the wsdl,  encase you alter the wsdl server
  );
which helps in any debugging and also to show what is going on from server-client.

and then just call the function exposed by the server

  echo $client->getQuote("genux");
and if you want to display the debugging information (request and response from the client-server)

  // display what was sent to the server (the request)
  echo "<p>Request  :".htmlspecialchars($client->__getLastRequest()) ."</p>";
  // display the response from the server
  echo  "<p>Response:".htmlspecialchars($client->__getLastResponse())."</p>";
here is the source code in full, if you save this as zend_soap_client_codecall.php

<?php
  $client = new SoapClient("http://localhost/zend_soap_server_codecall.php?wsdl",
    array(
      "trace"      => 1,        // enable trace to view what is happening
      "exceptions" => 0,        // disable exceptions
      "cache_wsdl" => 0)         // disable any caching on the wsdl, encase you alter the wsdl server
  );

  // get a response from the WSDL zend server function getQuote for the day monday
  echo $client->getQuote("genux");

  // display what was sent to the server (the request)
  echo "<p>Request :".htmlspecialchars($client->__getLastRequest()) ."</p>";
  // display the response from the server
  echo "<p>Response:".htmlspecialchars($client->__getLastResponse())."</p>";
?>
the output would be similar to

genux : Codecall was here!!Request :<?xml version="1.0"  encoding="UTF-8"?> <SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:ns1="http://localhost/projects/webservice/zend_soap_server_codecall.php"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getQuote><quote   xsi:type="xsd:string">genux</quote></ns1:getQuote></SOAP-ENV:Body></SOAP-ENV:Envelope> 
Response:<?xml version="1.0" encoding="UTF-8"?> <SOAP-ENV:Envelope  xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:ns1="http://localhost/projects/webservice/zend_soap_server.php"  xmlns:xsd="http://www.w3.org/2001/XMLSchema"  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"  SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><SOAP-ENV:Body><ns1:getQuoteResponse><return  xsi:type="xsd:string">genux : Codecall was  here!!</return></ns1:getQuoteResponse></SOAP-ENV:Body></SOAP-ENV:Envelope> 

of course you need to run the server on a web server instance on your localhost for the copy-paste code above, or just alter the http://localhost/ URLs to where you want to host the code.

Edited by genux, 13 April 2010 - 11:59 PM.


int coffeePerDay = 10; // need to cut down!!!

Codingfriends

#2
phpforfun

phpforfun

    Speaks fluent binary

  • Members
  • PipPipPipPipPipPipPipPip
  • 1,236 posts
PHP - SOAP – Server Coding Friends

Someone ban this tard
Checkout my new forum! http://adminreference.com/

#3
James.H

James.H

    Programming God

  • Members
  • PipPipPipPipPipPipPip
  • 866 posts
Thead closed.

Tutorials need to be unique.