Creating and Consuming Web Services With PHP
by Jean-Luc David
|
Finally, the web service responds with the result of our query wrapped
in a SOAP message. The result of the exchange rate between Canada and
the US is 1.3267. The result is displayed on the screen without the
SOAP headers.
HTTP/1.1 200 OK
Date: Tue, 10 Feb 2004 11:45:27 GMT
Server: Electric/1.0
Content-Type: text/xml
Content-Length: 492
X-Cache: MISS from www.xmethods.net
Connection: close
<?xml version='1.0' encoding='UTF-8'?>
<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'
xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/encoding/'
soap:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'>
<soap:Body>
<n:getRateResponse xmlns:n='urn:xmethods-CurrencyExchange'>
<Result xsi:type='xsd:float'>1.3267</Result></n:getRateResponse>
</soap:Body>
</soap:Envelope>
Creating a NuSOAP Web service
The next example will demonstrate how to create a web service using
NuSOAP. One of the nice features of NuSOAP is the web service summary
information and the dynamically generated WSDL files. Here is an
example of a web service summary:
We will now create a web service called CanadaTaxCalculator which will
calculate the Provincial & Federal sales tax for Ontario Canada
just like the XML-RPC example. Let's look at the code:
<?
require_once("nusoap.php");
$ns="http://localhost/nusoap";
First we must include our NuSOAP library and define the namespace of
the service. It is usually recommended that you designate a
distinctive URI for each one of your Web services.
$server = new soap_server();
$server->configureWSDL('CanadaTaxCalculator',$ns);
$server->wsdl->schemaTargetNamespace=$ns;
Next step, we instantiate the SOAP server and define the settings for
our WSDL file such as the service name and the namespace.
$server->register('CalculateOntarioTax',
array('amount' => 'xsd:string'),
array('return' => 'xsd:string'),
$ns);
Then we register our PHP tax calculation function. This step will make
the server "aware" of the existence of the CalculateOntarioTax method
and the values that will pass to and from the method. If you have
several methods, you must register each one separately.
function CalculateOntarioTax($amount){
$taxcalc=$amount*.15;
return new soapval('return','string',$taxcalc);
}
Then we invoke the service using the following line of code:
$server->service($HTTP_RAW_POST_DATA);
?>
That's it. Save your code in a file called "server.php", place the
file on your web server and voila! You can now view dynamic WSDL
formatted data by typing the following URL (be sure to substitute
"localhost" with your own server name):
http://localhost/server.php?wsdl
In fact, appending "?wsdl" to the end of any PHP NuSOAP server file
will dynamically produce WSDL code. Here's how our CanadaTaxCalculator
Web service is described using WSDL:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<definitions xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
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/"
xmlns:si="http://soapinterop.org/xsd"
xmlns:tns="http://localhost/nusoap"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns="http://schemas.xmlsoap.org/wsdl/"
targetNamespace="http://localhost/nusoap">
<types>
<xsd:schema targetNamespace="http://localhost/nusoap">
<xsd:import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
<xsd:import namespace="http://schemas.xmlsoap.org/wsdl/" />
</xsd:schema>
</types>
<message name="CalculateOntarioTaxRequest">
<part name="amount" type="xsd:string" />
</message>
<message name="CalculateOntarioTaxResponse">
<part name="return" type="xsd:string" />
</message>
<portType name="CanadaTaxCalculatorPortType">
<operation name="CalculateOntarioTax">
<input message="tns:CalculateOntarioTaxRequest" />
<output message="tns:CalculateOntarioTaxResponse" />
</operation>
</portType>
<binding name="CanadaTaxCalculatorBinding" type="tns:CanadaTaxCalculatorPortType">
<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
<operation name="CalculateOntarioTax">
<soap:operation
soapAction="http://localhost/nusoap/onttaxws.php/CalculateOntarioTax"
style="rpc" />
<input>
<soap:body use="encoded"
namespace="http://localhost/nusoap"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</input>
<output>
<soap:body use="encoded"
namespace="http://localhost/nusoap"
encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
</output>
</operation>
</binding>
<service name="CanadaTaxCalculator">
<port
name="CanadaTaxCalculatorPort"
binding="tns:CanadaTaxCalculatorBinding">
<soap:address location="http://localhost/nusoap/onttaxws.php" />
</port>
</service>
</definitions>
Creating a NuSOAP Web Service Client
What if we want to consume the web service we just created? Not a
problem at all. Let's build a client from scratch. First, we must
instantiate the NuSOAP client object and pass the WSDL file with the
relevant web service definitions into the client.
<?php
require_once('nusoap.php');
$wsdl="http://localhost/server.php?wsdl";
$client=new soapclient($wsdl, 'wsdl');
Next step, we create a set of parameters to pass into the Web service
and then remotely call the CalculateOntarioTax method. The example
shows us sending an amount of $15.00 into the web service to find out
how much tax we would have to pay in Ontario.
$param=array(
'amount'=>'15.00',
);
echo $client->call('CalculateOntarioTax', $param);
?>
REST
REST differs a great deal from SOAP and XML-RPC. First, it's not a
standard, whether formal or informal. Second, there is no standardized
toolkit or pre-built client and server classes in PHP. The strength of
REST is that you won't need special extensions or tools to develop web
services. The HTTP protocol specifications contains everything you
would need to transmit and receive XML messages.
REST, which stands for "Representational State Transfer", is a simpler
approach than XML-RPC or SOAP, using standard HTTP methods such as
GET, POST and PUT to send and retrieve XML data. You can then use
tools like PHP DOM, SAX, or even XSL to do the parsing. The downside
is that everything has to be built by hand (though REST toolkits and
frameworks are starting to appear in some languages). If you want to
develop REST web services, you must thoroughly understand XML and
HTTP. Expect to have to write a little more code yourself.
Consuming an XML Web service using REST
To pass XML data from one server to another, we will be using the cURL
PHP extensions. The Client URL Request Library is a versatile set of
classes that enable PHP to transmit and receive files via HTTP. The
data that is transmitted is a simple XML file, therefore you are not
required to create an elaborate server. No custom wrappers or APIs are
needed either. REST is increasing in popularity: in fact, Amazon.com
has created a popular web service designed around the REST
concept.
Let's look at the code for our REST web service client. First, we
define the file location and the name of the XML file; if you want to
dynamically generate the XML file, all you need to do is design a
custom PHP script that accepts parameters (through the query string),
incorporates your processing functions and outputs an XML file with
the "result":
<?
$rs="http://localhost/xmldata.xml";
$qs="";
Then we create an array which will contain the parameters we will pass
in the query string. Each one of the parameters is then urlencoded so
that it may pass without problems in the HTTP header:
$parray=array('amount'=>"15.00");
foreach($parray as $par=>$value){
$qs=$qs."$par=".urlencode($value)."&";}
$uri="$rs?$qs";
Then we instantiate the cURL object. The CURLOPT_RETURNTRANSFER
parameter specifies that we want the data to transmit even if errors
are encountered. We then execute the transfer and pass the resulting
data into a variable called $xml:
$cobj=curl_init($uri);
curl_setopt($cobj,CURLOPT_RETURNTRANSFER,1);
$xml=curl_exec($cobj);
curl_close($cobj);
echo $xml;
?>
Here is the code for the REST server. The program grabs the dollar
amount from the query string, executes the tax calculation then
outputs XML with the result:
<?
$amount=$_GET["amount"];
$taxcalc=$amount*.15;
echo "<?xml version=\"1.0\"?>";
echo "<taxinfo>";
echo "<result>".$taxcalc."</result>";
echo "</taxinfo>";
?>
Conclusion
With three different methods of consuming and producing web services
and tons of toolkits at your disposal, there is simply no reason why
you can't use PHP to develop web based XML applications. Be sure to
download our sample code and good luck.
Prev [1] [2]