Creating and Consuming Web Services With PHP
by Jean-Luc David
|
Pages: 1, 2
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.
ResourcesREST Wiki SOAP specification WSDL Specifications |
Share your questions or comments on this article in our forum.
(* You must be a member of XML.com to use this feature.)
Comment on this Article
| Titles Only | Titles Only | Newest First |
- Genrating WSDL Error!!
2005-12-26 15:35:35 Gulihsan [Reply]
when i click the link
http://localhost/soapserver.php?wsdl
it gives this messege
and no web service working
Only one top level element is allowed in an XML document. Error processing resource 'http://localhost/soapserver.php?wsdl'....
Notice: Undefined index: HTTPS in E:\Program Files\Apache Group\Apache2\htdocs\nusoap.php
- Genrating WSDL Error!!
2005-12-30 11:59:26 MikeBigg [Reply]
Greetings.
I am a NuSoap newbie trying to get the http://localhost/soaptest.php?WSDL to function with the newest version of NuSoap.
When I use:
require('nusoap.php');
$ss = new soap_server;
// Initialize WSDL support
$WSDLName = "'soaptest-1wsdl";
$nameSpace = "http://localhost/soap";
$ss->configureWSDL( $WSDLName , $nameSpace );
...
I (also) get this error:
Notice: Undefined index: HTTPS in <internal webserver path>/nusoap.php on line 4006
Any ideas anyone?
Mike B.
- Genrating WSDL Error!!
2007-02-15 01:13:40 serverscreen [Reply]
when i click the link
http://localhost/soapserver.php?wsdl
It gives the following error
Notice: Undefined index: HTTPS in
D:\apache\Apache2\htdocs\testing\nusoap\lib\nusoap.php on line 4006
Notice: Undefined variable: HTTP_RAW_POST_DATA in D:\apache\Apache2\htdocs\testing\nusoap\server.php on line 13
- Genrating WSDL Error!!
2007-07-11 01:52:37 ChinnuSuman [Reply]
replace the line 4006 with the following line..It works fine for me.
$HTTPS=((isset($_SERVER['HTTPS']))?$_SERVER['HTTPS'] : 'no');
- Genrating WSDL Error!!
- Genrating WSDL Error!!
- Genrating WSDL Error!!
- Pls Help
2005-10-24 20:10:11 NeMeSiS [Reply]
I did as you have stated in the article but i get the following errors with the server.php.
Please help.
Do you need anything other then
1-a brower with php support
2-nusoap.php
Notice: Undefined index: HTTPS in C:\PHP\ext\nusoap\lib\nusoap.php on line 4006
Notice: Undefined variable: HTTP_RAW_POST_DATA in D:\WebApps\test3\server.php on line 15
Also with the client.php file i get the error
Notice: Undefined index: in C:\PHP\ext\nusoap\lib\nusoap.php on line 5901
Please be kind enough to help me with this.
Thank you.
- Pls Help
2008-02-04 09:28:19 mour [Reply]
When i do:
http://localhost/server.php?wsdl
The message error appears in the screen:
Notice: Undefined variable: HTTP_RAW_POST_DATA in c:\program files\easyphp1-8\www\server.php on line 15
Warning: Cannot modify header information - headers already sent by (output started at c:\program files\easyphp1-8\www\server.php:15) in c:\program files\easyphp1-8\www\nusoap.php on line 3668
Please, What the origin of the error?
- Pls Help
2005-12-06 17:44:42 hoton [Reply]
You have to remember that "Notice:" errors don't really harm your application; it will still run, you'll just get errors on the page when you want to view it.
If it's really buggin you too much, put one of the following lines at the beginning of your script:
error_reporting(0);
-OR-
error_reporting(E_ERROR | E_WARNING | E_PARSE); //my fav
- Pls Help
- nusoap and require_once
2005-05-25 09:48:36 garbiner [Reply]
Hi,
nice article!
I have developed a WebService with nusoap but I have a problem: once I add a require_once('file.php'),WebService doen't work anymore.
Error
Response not of type text/xml
Responce
output started with file.php.
Thanks.
Andrea
- Help
2005-05-22 01:54:38 Bhavik [Reply]
Hi, nice article.
I am about to develop a (web-PHP) billing system for a company that is producing a billfor diffrent things.I want to make it software of the
company that uses a client server technology where all the users connect to the server and paythe bill.
how it is possible some code or by which method?
how billing system is to access the server software or vise versa?
so please help me how to make this possible
- nuSoap help
2005-03-11 08:12:53 gimly [Reply]
Hi, I am getting the following output when i run the client for CanadaTaxCalculator. Please help!
array(4) { ["faultcode"]=> string(6) "Server" ["faultactor"]=> string(0) "" ["faultstring"]=> string(26) "unable to serialize result" ["detail"]=> array(1) { ["soapVal"]=> string(0) "" } }
- nuSoap help
2005-03-22 14:06:39 john@activecode.org [Reply]
i got the same problem
- nuSoap help
- Great intro!
2004-12-16 02:04:15 perplexed [Reply]
Had some errors as did others, but read other comments and got it too work. SOAP, it's another buzz word for the CV.
2004-11-25 07:56:42 cocentaina [Reply]
Nice article. I had the same problem as Néstor, solved it with his help and the error message was:
[faultcode] => Server [faultactor] => [faultstring] => unable to serialize result [detail] => Array ( [soapVal] => )
- solution
2006-04-27 00:13:08 ersinkaradol [Reply]
Hello can you tell me the solution for the error
[faultcode] => Server [faultactor] => [faultstring] => unable to serialize result [detail] => Array ( [soapVal] => )
Thanks.
- solution
- Please help
2004-11-10 06:24:41 1956 [Reply]
I am about to develop a (web-PHP) reservation system for a company that is producing a virtual meeting software. The software of the
company uses a client server technology where all the users connect to the server and perform a meeting.
My reservation system is supposed to access the server software or vise versa. The server software is build in Delphi and my reservation system is going to be implemented in PHP.
How do I make the comunication between a delphi(server) application
and a PHP web application with web services?
Shall I need to use a third language like Java?
- Re: good starting and error
2004-10-27 22:58:34 Stormpixel [Reply]
Hi Nestor,
Thanks for the feedback about the article. I'm glad it was helpful to you.
Typically, you receive an XML response from a SOAP request. The XSD prefix stands for XML Schema Definition which defines the legal components of an XML document.
The line of code you mention sets up a string declaration within a schema. You can output pretty much anything you want including regular strings.
What was the error message you received?
Thanks,
Jean-Luc David
http://www.stormpixel.com
- good starting and error.
2004-10-26 10:03:27 nestorgm [Reply]
This article was a great kick into the web services world, form me. Thaks.
When I tried to test the basic examples, I found an error condition which made me look into the nusoap.php code and follow it for a few days.
After that, I realize that if I replace the line on the server
return new soapval('return','string'$taxcalc);
for
return new soapval('return','xsd:string',$taxcalc);
All the stuff worked fine.
Now I wonder why in your code, it worked the plain type 'string'.
Regards.
--Néstor
- How to handle DELETE using PHP REST
2004-10-04 01:11:23 Stormpixel [Reply]
The work is primarily done by your PHP server. You have to retrieve the method from the header, then execute the task you want.
For example, let's say your REST service adds and deletes records from a database. The server must first look at the header, if it has a DELETE method it would look for a parameter (let's say a ROWID) in the querystring of the URL and delete the corresponding ROWID in your database.
As I've outlined in the article, REST is effective and based on web standards. However, the onus is on the developer to build the guts of the service from scratch using the HTTP specs. That's why you couldn't find anything in the PHP docs.
Hope this information helps.
Thanks,
Jean-Luc David
http://www.stormpixel.com
--- Original Message ---
since the REST idea is to optimize the usage of HTTP methods (GET,PUT,DELETE,POST,etc). how do we handle DELETE, PUT or OPTION in php? I just couldn't find the way to handle DELETE in php4 doc.
- (REST) how well PHP supporting HTTP /1.1 spec?
2004-10-03 05:29:16 stupidiot [Reply]
thanx for the nice article, sample code do let me get an idea about implementation of REST in php.
i'm a php newbie, correct me if i were wrong..
since the REST idea is to optimize the usage of HTTP methods (GET,PUT,DELETE,POST,etc). how do we handle DELETE, PUT or OPTION in php?
i just couldn't find the way to handle DELETE in php4 doc.
- Wrong link for PHP
2004-03-25 06:39:20 Franck Guillaud [Reply]
There is a little mistake in the link for SOAP and PHP : the good one is :
http://dietrich.ganx4.com/nusoap/index.php
