#native_company# #native_desc#
#native_cta#

Using XML: A PHP Developer’s Primer, Part 4

By Adam Delves
on August 7, 2008

XML-RPC

In this article we will demonstrate how PHP can
be used to call upon web services provided by third part sites via an
XML-RPC server. We will also show you how to create your own XML-RPC and
use client-side Javascript to invoke procedures in your PHP scripts.

What is RPC?
RPC is an acronym for Remote
Procedure Call.
As the name suggests, RPC is a technology that provides an interface
for making procedure calls over a network. Remote procedure calls are
by no means a new technology. RPCs have been around since the
emergence of computer networks and applications that communicate via
these networks. Typically, two or more applications which need to
communicate over a network use a protocol (a “communication language” of sorts).
These protocols enable the two end points to send each other
instructions and invoke certain procedures. HTTP, SQL and
POP3 are all examples of RPC-like protocols.

The emergence of the Internet has made more applications network-aware
and has thrown them all into the same domain. The mish mash of different
protocols that are used by the ever-growing number of applications has made the task
of creating new applications daunting for developers. The developers now have to familiarize themselves with several different protocols. RPCs
address this problem by exposing a standard, generalized interface by
which a method residing at a remote endpoint can be invoked, and its
return value received like any other native procedure from within the
program code. The developer need not worry about how and in what
format the data is sent between the two endpoints. In some cases they may
be unaware that they are even using an RPC!

The XML-RPC Payload
XML-RPC is an RPC protocol which
uses XML mark-up to describe method calls and responses, making it ideal for use
over the Internet. In most cases, HTTP is used as the transport medium
for method calls and their responses. The XML request is sent in the body of an HTTP POST request and the response from the server is returned in the body of the HTTP response.

Calling An RPC
An RPC call needs to contain three pieces of information. The method
name, its parameters (if any) and the data type of each parameter:

<?xml version="1.0"
encoding="UTF-8" ?>

<methodCall>

   
<methodName>emailValidator.verify</methodName>

    <params>

       
<param><value><int>54</int></param>

       
<param><value><string>RG5H4</string></param>

    </params>

</methodCall>

The Response
Upon successful execution of the RPC, the response to the above call
would look something like this:

<?xml version="1.0"
encoding="UTF-8" ?>

<methodResponse>

    <params>

       
<param><value><boolean>1</boolean></param>

    </params>

</methodResponse>

If for any reason the method is
not executed,
the RPC server will return a fault response. The fault response contains a fault code
and description in the following format:

<?xml version="1.0"
encoding="UTF-8" ?>

<methodResponse>

    <params>

       
<param>

       
    <value>

       
       
<struct>

       
       
    <member>

       
   
       
   
<name>faultCode</name>

       
   
       
   
<value><int>1</int></value>

       
       
    </member>

       
       
    <member>

       
   
       
   
<name>faultString</name>

       
   
       
   
<value>Not enough parameters.</value>

       
       
    </member>

       
       
</struct>

       
    </vlaue>

       
</param>

    </params>

</methodResponse>

A detailed XML-RPC specification
can be found here.
XML-RPC and Objects
XML-RPC alone does not allow for
the accurate
implementation of object orientated method calls. Although the
serialized data from an object (i.e., all its properties) can
be encoded into a struct, there is no facility to describe the type and
the operations provided by the object, such as a class definition. It
is therefore up to the two end points (client and server) to handle the
data in the correct context. As the ethos behind RPC was
standardization and generalization, sending serialized objects via RPC
is not recommended for several reasons:
  • Both endpoints must respect the visibility of the object’s
    members (e.g: public, private, protected).
  • After each operation the data will need to be revalidated
    to ensure that it respects any constraints.
  • Serializing and unserializing an object is a resource
    intensive task
  • As a single operation typically affects only a single
    object property, much of the serialized data is redundant and gets passed back
    and forth unnecessarily.
The solution to this problem is to keep the object instance on the
server and transpose only its public operations to RPCs. It is up
to the server to keep track of and serialize individual object
instances. For example, a customer object may be transposed as follows:

Customer Object

RPC Methods mapped to customer object:

Customer.getAddress(id)

Customer.getName(id)

Customer.setName(id, newName)

Customer.find(pattern)

The RPC client only needs to work with one piece of data: the customer
ID. This is passed along with each RPC call and serves to uniquely
identify the object instance. Although the data still needs to be
serialized, this is now only the servers job and it retains complete
control over all the data that is connected with the customer.

Another solution is to use SOAP (Simple Object Access Protocol), an
application of RPC and WSDL (Web Services Description Language). It
provides a robust way to work with remote object instances. This will be
explored in more detail in the next article in this series.

XML-RPC in PHP

The PEAR XML-RPC
package is included with PEAR in the standard PHP installation. It provides both
an XML-RPC client and server. I will explain first how we go about calling RPCs from PHP.

More and more websites are making their services available
via RPC. This promotes the sharing of information and the re-usability
of existing services to enrich the content that web developers can
provide. For example, a typical web application may call on news
services, search engines and online payment services to provide the
functionality that would otherwise require code written by
in-house developers.

In the following example I will demonstrate how to use the
PEAR RPC client in PHP to call several APIs provided by the online photo sharing
service Flickr. The example will display the four most recent public pictures added to a specified users Flickr account.

Flickr

Flickr
is a new online photo-based service which allows its
users to upload, share, tag and add comments to their pictures as well
as order physical reprints. It also provides a web service API,
which is made accessible via RPC. The API allows the developer to
do anything a normal user can do but via the API. If you wish to
access the API, you first need to sign up for an account and obtain
an API
Key
, this needs to be passed as an argument to each RPC
called on Flickr.

The API’s provided by Flickr typically expose multiple
optional arguments. For this reason each RPC accepts a single parameter
containing a structure, each member of which is an argument that is to be
passed to the RPC. This enables the developer to send only the
parameters which are needed in any order:

<struct>

    <member>

       
<name>apiKey</name>

       
<value><string>123456</string></value>

    </member>

    <member>

       
<name>userName</name>

       
<value><string>visualAd</string></value>

    </member>

</struct>

The method response is always returned as a string in the form
of an XML document containing the data or response to the operation
requested. The documentation for each API describes the format of the
XML document returned. We can use the tools
provided to us by PHP to interpret this XML response.

Using the PHP XML-RPC Client
PEAR is included by default with
PHP. Provided the interpreter was not compiled with the -–without-pear
configuration option, the PEAR XML-RPC package will be available by
default. To include the RPC client in your scripts, use the following line:

require_once 'XML/RPC.php';

The XML-RPC client provides four objects:
  • XML_RPC_Client
    – provides the transport by which RPC calls are sent and RPC responses
    received.
  • XML_RPC_Message
    – used to store a RPC call and its parameters
  • XML_RPC_Value
    – Represents an XML-RPC value and its data type.
  • XML_RPC_Response
    – Holds an XML-RPC response.