Thursday, January 17, 2008

Tutorial - Hello World with WSDL Mode Using Web Service Framework for PHP

Web Service Framework for PHP (WSF/PHP) allows you to write web services and clients using WSDL. In there you are not writing the XML message manually, rather you only need to provide parameters and the framework generate the xml message for you. So this is a simple tutorial which allow you to write a Hellow World service and client from a WSDL.

Here is my WSDL.

<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:ns1="http://org.apache.axis2/xsd"
xmlns:wsaw="http://www.w3.org/2006/05/addressing/wsdl"
xmlns:http
="http://schemas.xmlsoap.org/wsdl/http/"
xmlns:ns0="http://MyTest"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/"
xmlns:soap
="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/"
targetNamespace="http://MyTest">


<wsdl:types>
<xs:schema xmlns:ns="http://MyTest"
attributeFormDefault="qualified"
elementFormDefault="qualified"
targetNamespace="http://MyTest">


<xs:element name="HelloWorld">
<xs:complexType>
<xs:sequence>
<xs:element name="greet" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="HelloWorldResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
</wsdl:types>
<wsdl:message name="HelloWorldRequest">

<wsdl:part name="parameters" element="ns0:HelloWorld"/>
</wsdl:message>
<wsdl:message name="HelloWorldResponse">

<wsdl:part name="parameters" element="ns0:HelloWorldResponse"/>
</wsdl:message>
<wsdl:portType name="HelloWorldPortType">

<wsdl:operation name="HelloWorld">
<wsdl:input message="ns0:HelloWorldRequest"
wsaw:Action
="urn:HelloWorld"/>


<wsdl:output message="ns0:HelloWorldResponse"
wsaw:Action="urn:HelloWorldResponse"/>

</wsdl:operation>
</wsdl:portType>

<wsdl:binding name="HelloWorldSOAP12Binding"
type
="ns0:HelloWorldPortType">

<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"
style
="document"/>


<wsdl:operation name="HelloWorld">
<soap12:operation
soapAction="urn:HelloWorld" style="document"/>


<wsdl:input>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>

<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>

<wsdl:service name="HelloWorld">
<wsdl:port name="HelloWorldSOAP12port_http"
binding="ns0:HelloWorldSOAP12Binding">

<soap12:address
location
="http://localhost:8080/axis2/services/HelloWorld"/>

</wsdl:port>
</wsdl:service>
</wsdl:definitions>



Just don't worry about what it means, But to use this you may need a little knowledge of finding the operation name and finding the arguments that we have to set in order to generate the request XML.

First to understand what are the operations and arguments, just check the 'wsdl:portType' element.
  <wsdl:portType name="HelloWorldPortType">

<wsdl:operation name="HelloWorld">
<wsdl:input message="ns0:HelloWorldRequest" wsaw:Action="urn:HelloWorld"/>

<wsdl:output message="ns0:HelloWorldResponse" wsaw:Action="urn:HelloWorldResponse"/>
</wsdl:operation>
</wsdl:portType>


So you can see this has one operation with the name "HelloWorld" and it contains both input and output messages. Anyway this doesn't reveal the format of the message. In order to have a clue on that, you have to go one level up in the WSDL.

 <wsdl:message name="HelloWorldRequest">

<wsdl:part name="parameters" element="ns0:HelloWorld"/>
</wsdl:message>
<wsdl:message name="HelloWorldResponse">

<wsdl:part name="parameters" element="ns0:HelloWorldResponse"/>
</wsdl:message>


Oops!, you will see this again point to another upper level through the 'element' attribute. Actually It is where the schema of your message is shown. First we will check 'HelloWorld' element.
        <xs:element name="HelloWorld">
<xs:complexType>
<xs:sequence>
<xs:element name="greet" type="xs:string"/>

</xs:sequence>
</xs:complexType>
</xs:element>


Here is the schema of your "HelloWorld" XML, I can see it validate an XML like this..

<HelloWorld xmlns="the namespace">
<greet>Hiro</greet>
</HelloWorld>

Don't worry, here you dont' need to understand the XML. just keeping in mind that we have to provide the argument 'greet' when calling HelloWorld.

The same way we will can expect the response message.
<HelloWorldResponse xmlns="the namespace">
<return>Welcome Hiro!</return>
</HelloWorldReponse>
So it is all about the explanation of the WSDL. We will go to the real steps of the tutorial

Building the Provider of the Web Service.. Here I have done explanation inline in each line.

<?php
/**
* Service.php
*/


/* This is where your logic is
Remeber in the WSDL we had "HelloWorld" operation with name argument */

function HelloWorld($name)
{

/* Remember in the response we had 'return' element */
return array("return"=> "welcome ".$name."!");

}

/* Map of the service opertion "HelloWorld" to php functions "HelloWorld" */
$operations = array("HelloWorld" => "HelloWorld");


/* just tell your function parameters should be in mixed format,
that is here parameter will be the string with the name in it*/

$opParams = array("HelloWorld" => "MIXED");

/* Created the WSService */

$svr = new WSService(array("wsdl" => "HelloWorld.wsdl",
"operations" => $operations,
"opParams" => $opParams));


/* Reply the client */
$svr->reply();

?>


Then you may put that in the htdocs directory to deploy with the Apache Server. I put it that directly in the htdocs directory. So my service endpoint is
http://localhost/Service.php.

Remember you restart the Apache server after you did this..

Just go to the browser and type "http://localhost/Service.php". This will give you the list of deployed services and their operations. Confirm your service is in there.

Then start writing the PHP web service client ..


<?php

/*
* Client.php
*/


/* create the WSClient with the given WSDL and my service endpoint
Note: Here im overwriting the endpoint declared in the WSDL */

$wsclient = new WSClient( array(

"wsdl" => "HelloWorld.wsdl",
"to" => "http://localhost/Service.php"));

/* we need to take the proxy object to call the wsdl operation */

$proxy = $wsclient->getProxy();

/* Right here I'm calling the HelloWorld function with argument "Hiro"
Remeber in the WSDL we had "HelloWorld" operation with name argument */

$ret_val = $proxy->HelloWorld(array("name" => "Hiro"));


/* Retrive the response. Just to recall, response had the element 'return' */
echo $ret_val["return"]."\n";

?>

It is all coding you should do. Now just go to a command line and run

php Client.php

or go to the browser and type

http://localhost/Client.php

If you retrieve exactly what the server set, You are done.

No comments: