0% found this document useful (0 votes)
92 views

Developing Web Services Using PHP

The document discusses developing web services using PHP. It provides an overview of web services and describes how to create a SOAP web service using PHP by defining a WSDL, creating a PHP script with the service functions, disabling the WSDL cache, instantiating a SoapServer object using the WSDL, adding functions to the server, and handling requests. An example gets a catalog entry based on an ID and returns HTML.

Uploaded by

Faizan Khan
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
92 views

Developing Web Services Using PHP

The document discusses developing web services using PHP. It provides an overview of web services and describes how to create a SOAP web service using PHP by defining a WSDL, creating a PHP script with the service functions, disabling the WSDL cache, instantiating a SoapServer object using the WSDL, adding functions to the server, and handling requests. An example gets a catalog entry based on an ID and returns HTML.

Uploaded by

Faizan Khan
Copyright
© Attribution Non-Commercial (BY-NC)
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

Developing Web Services Using PHP

A web service consists of a server to serve requests to the web service and a client to invoke
methods on the web service. The PHP class library provides the SOAP extension to develop
SOAP servers and clients and the XML-RPC extension to create XML-RPC servers and clients.
Before I delve further into developing web services with PHP, I shall briefly discuss web
services.

Introduction to Web Services

A web service is a software system designed for interoperable interaction over a network. A web
service is defined with a WSDL (Web Services Description Language) document, and other
systems interact with the web service using SOAP messages, transferred using HTTP with an
XML serialization. A web service is an abstract resource that provides a set of functions and is
implemented by an agent, which sends and receives messages. A provider entity provides the
functionality of a web service with a provider agent and a requester entity uses the web service
functionality with a requester agent. Web services implement various technologies, some of
which are XML, SOAP, and WSDL. XML is a standard format for data exchange. Web service
requests and responses are sent as XML messages. The elements and attributes that may be
specified in an XML document are specified in an XML Schema. SOAP provides a standard
framework for packaging and exchanging XML messages. WSDL is an XML document in the
http://schemas.xmlsoap.org/wsdl/ namespace for describing a web service as a set of endpoints
operating on messages. A WSDL document specifies the operations (methods) provided by a
web service and the format of the XML messages.

Installing the PHP Web Services Extensions

The SOAP and XML-RPC extensions are packaged with the PHP 5 installation. The SOAP
extension and the XML-RPC extension are not enabled by default in a PHP installation. To
enable the SOAP and XML-RPC extensions add the following extension directives in the
php.ini configuration file.

extension=php_xmlrpc.dll
extension=php_soap.dll

Restart the Apache 2 server to activate the SOAP and XML-RPC extensions. The SOAP
extension supports subsets of the SOAP 1.1, SOAP 1.2, and WSDL 1.1 specifications.

Creating a SOAP Web Service

After activating the SOAP extension in the PHP configuration file, a SOAP server and a SOAP
client may be created using the SOAP PHP class library. A SOAP server serves web service
requests and a SOAP client invokes methods on the SOAP web service. The SOAP library
provides various functions for creating a SOAP server and a SOAP client. Some of the
commonly used SOAP functions are discussed in Table 1.
Table 1. SOAP functions

Method Description

Creates a SoapServer object. The wsdl


SoapServer->__construct( mixed wsdl [, parameter specifies the URI of the WSDL.
array options] ) SoapServer options such as SOAP version
may be specified in the options array.

Adds one or more PHP functions that will


handle SOAP requests. A single function may
SoapServer->addFunction( mixed functions )
be added as a string. More than one function
may be added as an array.

SoapServer->fault() SoapServer fault indicating an error.

SoapServer->getFunctions() Returns a list of functions.

Processes a SOAP request, invokes required


SoapServer->handle()
functions and sends back a response.

Sets the class that will handle SOAP requests.


SoapServer->setClass(string class_name [, Exports all methods from the specified class.
mixed args [, mixed ...]] ) The args are used by the default class
constructor.

SoapHeader->__construct() Creates a SOAP header.

SoapClient->__soapCall( string
function_name, array arguments [, array
Invokes a SOAP function.
options [, mixed input_headers [, array
&output_headers]]] )

SoapClient->__doRequest() Performs a SOAP request.

SoapClient->__getFunctions() Returns a list of SOAP functions.

SoapClient->__getTypes() Returns a list of SOAP types.

Creating a SOAP Server

Before we create a SOAP server we need to create a WSDL document defining the web service.
The WSDL document defines the operations that the web service provides. I will create an
example web service that provides an operation getCatalogEntry, which returns a catalog entry
for a catalog ID. A WSDL is an XML document in the http://schemas.xmlsoap.org/wsdl/
namespace. Some of the elements of a WSDL document are discussed in Table 2.

Table 2. WSDL elements

Element Description

definitions Root element of a WSDL document.

Specifies data type definitions for the messages exchanged by the web service. XML
types
Schema is the recommended type system.

Defines the data being transmitted. A message consists of one or more parts. A part is
message
associated with a type.

portType Defines a set of operations and the input-output messages for each operation.

An action (method) supported by the service. Each operation consists of input and
operation
output messages.

input Specifies a message format for the request.

output Specifies a message format for the response.

Defines message format and protocol details for operations and messages for a
binding
particular portType.

service Specifies a group of ports.

port Defines an endpoint by associating an address with a binding.

Next, create a WSDL document for the example web service. The example WSDL document,
catalog.wsdl, defines message elements getCatalogRequest and getCatalogResponse for
the request and response messages. In the WSDL document define a portType,
CatalogPortType, for the getCatalogEntry operation that returns a catalog entry as a HTML
string for a string catalogId. Define a binding, CatalogBinding, for the getCatalogEntry
operation and the input output messages. The soap:binding element specifies that the binding is
bound to the SOAP protocol format. The soap:operation element specifies information for the
operation. The soap:body element specifies how the message parts appear inside the SOAP
Body element. Define a service CatalogService that consists of a port, CatalogPort, which is
associated with the CatalogBinding binding. The soap:address element specifies the URI of
an address. The catalog.wsdl WSDL document is listed below.
<?xml version ='1.0' encoding ='UTF-8' ?>
<definitions name='Catalog'
targetNamespace='http://example.org/catalog'
xmlns:tns=' http://example.org/catalog '
xmlns:soap='http://schemas.xmlsoap.org/wsdl/soap/'
xmlns:xsd='http://www.w3.org/2001/XMLSchema'
xmlns:soapenc='http://schemas.xmlsoap.org/soap/
encoding/'
xmlns:wsdl='http://schemas.xmlsoap.org/wsdl/'
xmlns='http://schemas.xmlsoap.org/wsdl/'>

<message name='getCatalogRequest'>
<part name='catalogId' type='xsd:string'/>
</message>
<message name='getCatalogResponse'>
<part name='Result' type='xsd:string'/>
</message>

<portType name='CatalogPortType'>
<operation name='getCatalogEntry'>
<input message='tns:getCatalogRequest'/>
<output message='tns:getCatalogResponse'/>
</operation>
</portType>

<binding name='CatalogBinding' type=


'tns:CatalogPortType'>
<soap:binding style='rpc'
transport='http://schemas.xmlsoap.org/soap/http'
/>
<operation name='getCatalogEntry'>
<soap:operation soapAction='urn:localhost-catalog#
getCatalogEntry'/>
<input>
<soap:body use='encoded' namespace=
'urn:localhost-catalog'
encodingStyle='http://schemas.xmlsoap.org/soap
/encoding/'/>
</input>
<output>
<soap:body use='encoded' namespace=
'urn:localhost-catalog'
encodingStyle='http://schemas.xmlsoap.org/soap/
encoding/'/>
</output>
</operation>
</binding>

<service name='CatalogService'>
<port name='CatalogPort' binding=
'CatalogBinding'>
<soap:address location='http://localhost/
soap-server.php'/>
</port>
</service>
</definitions>
Copy the catalog.wsdl document to the C:\Apache2\htdocs directory, the directory in which PHP
scripts are run. Create a PHP script, soap-server.php, to define the operations provided by the
CatalogService web service. In the soap-server.php script define a function
getCatalogEntry() that takes a catalogId as an argument and returns a string consisting of an
HTML document. The HTML document string returned comprises of the catalog entry for the
specified catalogId.

function getCatalogEntry($catalogId) {
if($catalogId=='catalog1')
return "<HTML> … </HTML>";
elseif ($catalogId='catalog2')
return "<HTML>…</HTML>";

The WSDL cache is enabled by default. Disable the WSDL cache by setting the
soap.wsdl_cache_enabled configuration option to 0.

ini_set("soap.wsdl_cache_enabled", "0");

Create a SoapServer object using the catalog.wsdl WSDL.

$server = new SoapServer("catalog.wsdl");

Add the getCatalogEntry function to the SoapServer object using the addFunction()
method. The SOAP web service provides the getCatalogEntry operation.

$server->addFunction("getCatalogEntry");

Handle a SOAP request.

$server->handle();

The soap-server.php script is listed below.

<?php
function getCatalogEntry($catalogId) {
if($catalogId=='catalog1')

return "<HTML>
<HEAD>
<TITLE>Catalog</TITLE>
</HEAD
<BODY>
<p> </p>
<table border>
<tr><th>CatalogId</th>
<th>Journal</th><th>Section
</th><th>Edition</th><th>
Title</th><th>Author</th>
</tr><tr><td>catalog1</td>
<td>IBM developerWorks</td><td>
XML</td><td>October 2005</td>
<td>JAXP validation</td>
<td>Brett McLaughlin</td></tr>
</table>
</BODY>
</HTML>";

elseif ($catalogId='catalog2')

return "<HTML>
<HEAD>
<TITLE>Catalog</TITLE>
</HEAD
<BODY>
<p> </p>
<table border>

<tr><th>CatalogId</th><th>
Journal</th><th>Section</th>
<th>Edition</th><th>Title
</th><th>Author
</th></tr><tr><td>catalog1
</td><td>IBM developerWorks</td>
<td>XML</td><td>July 2006</td>
<td>The Java XPath API
</td><td>Elliotte Harold</td>
</tr>
</table>
</BODY>
</HTML>";
}

ini_set("soap.wsdl_cache_enabled", "0");
$server = new SoapServer("catalog.wsdl");
$server->addFunction("getCatalogEntry");
$server->handle();

?>

In the next section, I will create a SOAP client to send a request to the SOAP server.

Creating a SOAP Client

Create a PHP script, soap-client.php, in the C:\Apache2\htdocs directory. In the PHP script,
create a SOAP client using the SoapClient class. The WSDL document, catalog.wsdl, is
specified as an argument to the SoapClient constructor. The WSDL document specifies the
operations that are available to the SOAP client.

$client = new SoapClient("catalog.wsdl");

Specify the catalogId for which a catalog entry is to be retrieved. Invoke the getCatalogEntry
method of the SOAP web service.

$catalogId='catalog1';
$response = $client->getCatalogEntry($catalogId);

Output the response to the browser.

echo $response;

The soap-client.php script is listed below.

<?php
$client = new SoapClient("catalog.wsdl");
$catalogId='catalog1';
$response = $client->getCatalogEntry($catalogId);
echo $response;
?>

Invoke the soap-client.php PHP script with the URL http://localhost/soap-client.php.The catalog
entry for the catalog1 catalogId gets output as shown in Figure 1.
Figure 1. Invoking the SOAP client

Creating an XML-RPC Web Service

XML-RPC is a specification and a set of implementations designed for applications to make


remote procedure calls over the network. The remote procedure calls are made using HTTP as
the transport and XML as the encoding.
Structure of an XML-RPC Request and Response

An XML-RPC message is an HTTP-POST request. The request body is in XML format. The
request is sent to an XML-RPC server, which runs some business logic and returns a response in
the form of XML. An example XML-RPC request is listed below.

POST /php/xmlrpc-server.php HTTP/1.0


User-Agent: Example Client
Host: localhost
Content-Type: text/xml
Content-length: 190

<?xml version="1.0"?>
<methodCall>
<methodName>getCatalog</methodName>
<params>
<param>
<value><string>catalog1
</string></value>
</param>
</params>
</methodCall>

The URI in the header, /php/xmlrpc-server.php specifies the server URI to which the request is
sent. The HTTP version is also specified. The User-Agent and Host are required to be specified.
The Content-Type is text/xml and the Content-Length specifies the content length.

The request body is in XML with root element as methodCall. The methodCall element is
required to contain a sub-element methodName which specifies the name of the method to be
invoked as a string. If the XML-RPC request has parameters, the methodCall element contains
sub-element params. The params element contains one or more param elements. Each of the
param elements contains a value element. The param value may be specified as a string, a
Boolean, a four-byte signed integer, double-precision signed, floating point number, date/time, or
base-64 encoded binary. The sub-element of value in which a param value is specified is
different for different value types. If a type is not specified the default type is string. The sub-
elements for the value types are listed in Table 3.

Table 3. Value elements

Value Type Element

ASCII String <string>

Four-byte signed integer <i4> or <int>


Boolean <boolean>

Double-precision signed or floating point number. <double>

Date/time <dateTime.iso8601>

Base-64 encoded binary. <base64>

A param value may also be of type <struct>. A <struct> element consists of <member>
elements. Each <member> element contains a <name> element and a <value> element. An
example of struct value is listed below.

<struct>
<member>
<name>catalogId</name>
<value><string>catalog1
</string></value>
</member>
<member>
<name>journal</name>
<value><string>IBM developerWorks
</string></value>
</member>
</struct>

A value element in a member element may be of any of the param data types including struct.
A param type may also be of type <array>. An <array> element consists of of a <data>
element, which consists of one or more <value> elements. An example of an <array> param
value is listed below.

<array>
<data>
<value><i4>1</i4></value>
<value><string>IBM developerWorks
</string></value>
<value>XML</value>
<value><string>Introduction to dom4j
</string></value>
<value><string>Deepak Vohra</string
></value>
</data>
</array>

A <value> element in a <data> element may consist of any of the data types including struct
and array. The server response to an XML-RPC request is in the format of XML. An example
response is listed below.

HTTP/1.1 200 OK
Connection: close
Content-Length: 190
Content-Type: text/xml
Date:
Server: Example Server

<?xml version="1.0"?>
<methodResponse>
<params>
<param>
<value><string>Introduction
to SQLXML</string></value>
</param>
</params>
</methodResponse>

If an error has not occurred, the server response returns "200 OK." The Connection header
specifies the state of the connection after the response is completed. For non-persistent
connection the Connection header value is "close." The Content-Type is text/xml. The
response body is in XML format with root element as methodResponse. The methodResponse
element consists of a single <params> element, which consists of a single <param> element. The
<param> element contains a single <value> element.

Instead of a <params> element a methodResponse element may also consists of a single


<fault> element. The <fault> element contains a <value> element, which contains a
<struct> element with two <member> elements faultCode of type integer and faultString of
type string. An example of a XML-RPC server response with a <<fault> element is listed
below.

HTTP/1.1 200 OK
Connection: close
Content-Length: 190
Content-Type: text/xml
Date:
Server: Example Server

<?xml version="1.0"?>
<methodResponse>
<fault>
<value>
<struct>
<member>
<name>faultCode</name>
<value><int>4</int
></value>
</member>
<member>
<name>faultString</name>
<value><string>No such Method.
</string></value>
</member>
</struct>
</value>
</fault>
</methodResponse>

Creating an XML-RPC Server

The PHP XML-RPC extension is a PHP implementation of the XML-RPC specification. The
XML-RPC PHP class library provides functions to create a XML-RPC server and invoke
methods on the server. Some of the commonly used XML-RPC functions are discussed in Table
4.

Table 4. XML-RPC PHP functions

Function Description

xmlrpc_server_create () Creates an XML-RPC server

xmlrpc_encode_request ( string
Generates XML for a method request or response.
method, mixed params [, array
output_options] ) Returns a string or FALSE on error.

xmlrpc_encode ( mixed value ) Generates XML for a PHP variable.

xmlrpc_decode_request ( string xml,


string &method [, string encoding] Decodes XML into PHP. Returns an array.
)

xmlrpc_get_type ( mixed value ) Returns XML-RPC data types, for example "struct",
"int", "string", "base64" for a PHP value.

xmlrpc_set_type ( string &value, Sets xmlrpc type, base64, or datetime for a PHP string
string type ) value. Returns True or False on error.

xmlrpc_server_register_method ( Registers PHP function to a web service method. The


resource server, string method_name value is the same as the value of the
method_name, string function )
methodName element in the XML-RPC request.

xmlrpc_server_call_method ( Parses XML request and invokes method. Returns result


resource server, string xml, mixed of method call. The user_data parameter specifies
user_data [, array output_options]
any application data for the method handler function.
)
The output_options parameter specifies a hashed
array of options for generating response XML. The
following options may be specified. output_type:
Specifies output data type; "php" or "xml". Default data
type is "xml". If output type is "php" other values are
ignored. verbosity: Specifies compactness of generated
message.escaping: Specifies if and how to escape some
characters.version: Specifies version of XML to use.
Value may be "xmlrpc", "soap 1.1" and "simple".
Version may also be set to "auto", which specifies to
use the version the request came in. encoding:
Specifies the encoding of the data. Default is "iso-8859-
1".Example value of the output_options parameter
is as follows.$output_options = array( "output_type" =>
"xml", "verbosity" => "no_white_space", "escaping" =>
array("markup", "non-ascii", "non-print"), "version" =>
"xmlrpc", "encoding" => "utf-8" );

xmlrpc_is_fault ( array arg ) Determines if an array value represents XML-RPC fault.

xmlrpc_server_destroy ( resource
Destroys a server resource.
server )

Create a PHP script, xmlrpc-webservice.php, in the C:/Apache2/htdocs directory. In the PHP


script, define a function, hello_func. Any function that is invoked by a client is required to take
three parameters: the first parameter is the name of the XML-RPC method invoked. The second
parameter is an array containing the parameters sent by the client. The third parameter is the
application data sent in the user_data parameter of the xmlrpc_server_call_method()
function. In the hello_func function, retrieve the first parameter, which is a name sent by the
client, and output a Hello message.

function hello_func($method_name, $params, $app_data)

{
$name = $params[0];
return "Hello $name.";
}

Create an XML-RPC server using the xmlrpc_server_create() method.

$xmlrpc_server=xmlrpc_server_create();

If a server does not get created the xmlrpc_server_create method returns FALSE. Register the
hello_func function with the server using the xmlrpc_server_register_method method. The
first argument to the xmlrpc_server_register_method method is the XML-RPC server
resource. The second argument is name of the method that is provided by the web service, which
is the <methodName> element value in a XML-RPC request. The third argument is the PHP
function to be registered with the server.

$registered=xmlrpc_server_register_method
($xmlrpc_server, "hello", "hello_func" );

If the PHP function gets registered, the xmlrpc_server_register_method returns TRUE.

Creating an XML-RPC Client

Next, I shall create a XML-RPC client to send a request to the XML-RPC server. First, specify
the XML string to be sent in the request.

$request_xml = <<< END


<?xml version="1.0"?>
<methodCall>
<methodName>hello</methodName>
<params>
<param>
<value>
<string>Deepak</string>
</value>
</param>
</params>
<methodCall>
END;

To escape XML in PHP, <<<END ….END; is used. An XML document demarker other END may
also be used. The methodCall element specifies the web service method that is to be invoked.
Invoke the web service method using the xmlrpc_server_call_method function. The first
argument to the xmlrpc_server_call_method function is the server resource. The second
argument is the string containing the XML-RPC request. The third argument is the application
data that is sent to the third parameter of the method handler function.

$response=xmlrpc_server_call_method( $xmlrpc_server,
$request_xml, '', array(output_type => "xml"));

Output the XML-RPC response from the server.

print $response;

The PHP script, xmlrpc-webservice.php, is listed below.

<?php
function hello_func($method_name, $params, $app_data)
{
$name = $params[0];
return "Hello $name.";
}

$xmlrpc_server=xmlrpc_server_create();
$registered=xmlrpc_server_register_method
($xmlrpc_server, "hello", "hello_func" );

$request_xml = <<< END


<?xml version="1.0"?>
<methodCall>
<methodName>hello</methodName>
<params>
<param>
<value>
<string>Deepak</string>
</value>
</param>
</params>
</methodCall>
END;
$response=xmlrpc_server_call_method( $xmlrpc_server,
$request_xml, '', array(output_type => "xml"));
print $response;
?>

Copy the xmlrpc-webservice.php script to the C:/Apache2/htdocs directory. Invoke the PHP
script with the URL http://localhost/xmlrpc-webservice.php. The response from the server gets
output to the browser as shown in Figure 2.
Figure 2. Response from XML-RPC web service

To demonstrate an error in the request, returned as a <fault> element in the response XML,
make the request XML not valid XML. For example replace </methodCall> with
<methodCall> in the $request_xml. Invoke the xmlrpc-webservice.php. The response from the
server is returned as a <fault> element that consists of a struct element value, which consists
of faultCode and faultString members, as shown in Figure 3.
Figure 3. Response as fault element

You might also like