PEAR is archived and read-only

This mirror preserves historical PEAR package releases and metadata so existing references remain available.

Home » Web Services » XML_RPC » Manual

PHP implementation of the XML-RPC protocol. This is a PEAR-ified version of Useful inc's XML-RPC for PHP. It has support for HTTP transport, proxies and authentication.

Introduction

Introduction – General introduction XML-RPC is a format devised by Userland Software for achieving remote procedure call via XML. XML-RPC has its own web site, www.XmlRpc.com. The most common implementations of XML-RPC available at the moment use HTTP as the transport. A list of implementations for other languages such as Perl and Python can be found on the www.xmlrpc.com. This collection of PHP classes provides a framework for writing XML-RPC clients and servers in PHP. Acknowledgements This package has been orginially written by Edd Dumbill of Useful Information Company, so he deservers most of the credits. Apart from that following people have contributed to the initial codebase that is still being maintained by Edd: Jim Winstead <jimw at php dot net> Peter Kocks <peter.kocks at baygate dot com> Nicolay Mausz <mausz at flying-dog dot com> Ben Margolin <ben at wendy.auctionwatch dot com> Dan Libby <dan at libby dot com> Gaetano Giunta <g.giunta at libero dot it> Idan Sofer <i_sofer at yahoo dot com> Giancarlo Pinerolo <ping at alt dot it> Justin Miller <justin at voxel dot net> Manifest - Files in the package Server.php the XML-RPC server class. include() this to get server functionality. RPC.php the XML-RPC client classes. include() this to get client functionality.

Support

Support – Getting support for XML_RPC

Online Support

The package is offered "as-is" without any warranty or commitment to support. However, informal advice and help is available via the PEAR user mailing list and XML-RPC.com.

The Jellyfish Book

Together with Simon St.Laurent and Joe Johnston, Edd Dumbill wrote a book on XML-RPC for O'Reilly and Associates on XML-RPC. It features a rather fetching jellyfish on the cover.

Complete details of the book are available from O'Reilly's web site.

If you've benefitted from the effort he has put into writing this software, then please consider buying the book!

Examples

Examples – Usage examples for the XML_RPC package

Using a Client to Get Info About the Latest PEAR Release

<?php
require_once 'XML/RPC.php';

/*
 * Get info about the most recently released PEAR package
 */
$params = array(new XML_RPC_Value(1, 'int'));
$msg = new XML_RPC_Message('release.getRecent', $params);

$cli = new XML_RPC_Client('/xmlrpc.php', 'pear.php.net');

// If you want to turn debugging on...
// $cli->setDebug(1);

// If your payload requires extra lines to stay in tact...
// NOTE: The $remove_extra_lines property was added in Version 1.4.6.
// $cli->remove_extra_lines = false;

// If inspect the XML request sent to the server...
// $msg->createPayload();
// logit($msg->payload);  // Hypothetical function.

$resp = $cli->send($msg);

if (!$resp) {
    echo 'Communication error: ' . $cli->errstr;
    exit;
}

if (!$resp->faultCode()) {
    $val = $resp->value();
    $data = XML_RPC_decode($val);
    echo $data[0]['name'] . ' is at version ' . $data[0]['version'];
} else {
    /*
     * Display problems that have been gracefully cought and
     * reported by the xmlrpc.php script
     */
    echo 'Fault Code: ' . $resp->faultCode() . "\n";
    echo 'Fault Reason: ' . $resp->faultString() . "\n";
}

// To inspect the XML response from the server...
// NOTE: The $response_payload property was added in Version 1.4.6.
// logit($msg->response_payload);  // Hypothetical function.
?>

A Complete Client and Server Combination

Here is the server script. It's named xmlrpc.php and located in the document root of the web server at localhost:

<?php
require_once 'XML/RPC/Server.php';

/*
 * Declare the functions, etc.
 */
function returnTimes2($params) {
    $obj = new some_class_name;
    return $obj->returnTimes2($params);
}

class some_class_name {
    function returnTimes2($params) {
        $param = $params->getParam(0);

        // This error checking syntax was added in Release 1.3.0
        if (!XML_RPC_Value::isValue($param)) {
            return $param;
        }

        $val = new XML_RPC_Value($param->scalarval() * 2, 'int'); 
        return new XML_RPC_Response($val);
    }
}

$some_object = new some_class_name;


/*
 * Establish the dispatch map and XML_RPC server instance.
 */
$server = new XML_RPC_Server(
    array(
        'function_times2' => array(
            'function' => 'returnTimes2'
        ),
        'class_paamayim_nekudotayim_times2' => array(
            'function' => 'some_class_name::returnTimes2'
        ),
        'class_times2' => array(
            'function' => array('some_class_name', 'returnTimes2')
        ),
        'object_times2' => array(
            'function' => array($some_object, 'returnTimes2')
        ),
    ),
    1  // serviceNow
);
?>

And here is the client script:

<?php
require_once 'XML/RPC.php';

$input = 8;
$params = array(new XML_RPC_Value($input, 'int'));
$msg = new XML_RPC_Message('function_times2', $params);

$cli = new XML_RPC_Client('/xmlrpc.php', 'localhost');
// $cli->setDebug(1);
$resp = $cli->send($msg);

if (!$resp) {
    echo 'Communication error: ' . $cli->errstr;
    exit;
}

if (!$resp->faultCode()) {
    $val = $resp->value();
    echo $input . ' times 2 is ' . $val->scalarval();
} else {
    /*
     * Display problems that have been gracefully cought and
     * reported by the xmlrpc.php script.
     */
    echo 'Fault Code: ' . $resp->faultCode() . "\n";
    echo 'Fault Reason: ' . $resp->faultString() . "\n";
}
?>

Automatically encoding data

The XML_RPC_encode() function automatically converts PHP data into the format needed by the XML_RPC library.

<?php
require_once 'XML/RPC.php';

$data = fetch_row_from_db();  //  Hypothetical example.

$params = array(XML_RPC_encode($data));
$msg = new XML_RPC_Message('some_function_name', $params);

$cli = new XML_RPC_Client('/xmlrpc.php', 'pear.php.net');
$resp = $cli->send($msg);

// Process the same way as the other examples...
?>

API

API – Class documentation of the package

XML_RPC_Client

This is the basic class used to represent a client of an XML-RPC server.

Creation

The constructor has the following syntax:

$client = new XML_RPC_Client ( string $path , string $server , integer $port , string $proxy , integer $proxy_port , string $proxy_user , string $proxy_pass )

string $path

the path and name of the RPC server script you want the request to go to

string $server

the URL of the remote server to connect to. If this parameter doesn't specify a protocol and $port is 443, ssl:// is assumed.

integer $port

a port for connecting to the remote server. Defaults to 80 for http:// connections and 443 for https:// and ssl:// connections.

string $proxy

the URL of the proxy server to use, if any. If this parameter doesn't specify a protocol and $port is 443, ssl:// is assumed.

integer $proxy_port

a port for connecting to the remote server. Defaults to 8080 for http:// connections and 443 for https:// and ssl:// connections.

string $proxy_user

a user name for accessing the proxy server

string $proxy_pass

a password for accessing the proxy server

In order to use SSL connections, your PHP installation must have the openssl extension enabled.

Here's an example client set up to query Userland's XML-RPC server at betty.userland.com:

<?php
$client = new XML_RPC_Client('/RPC2', 'betty.userland.com');
?>

Methods

This class supports the following methods.

send()

This method takes the form:

$response = $client->send ( $xmlrpc_message , $timeout )

Where $xmlrpc_message is an instance of XML_RPC_Message and $response is an instance of XML_RPC_Response (see API).

The $timeout is optional, and will be set to 0 (wait forever) if omitted. This timeout value is passed to fsockopen().

If the value of $response is 0 rather than an XML_RPC_Response object, then this signifies an I/O error has occured. You can find out what the I/O error was from the values $client->errno and $client->errstring.

In addition to low-level errors, the XML-RPC server you were querying may return an error in the XML_RPC_Response object. See API for details of how to handle these errors.

setCredentials()

$client->setCredentials ( $username , $password )

This method sets the username and password for authorizing the client to a server. With the default (HTTP) transport, this information is used for HTTP Basic authorization.

setDebug()

$client->setDebug ( $debugOn )

$debugOn is either 0 or 1 depending on whether you require the client to print debugging information to the browser. The default is not to output this information.

The debugging information includes the raw data returned from the XML-RPC server it was querying, and the PHP value the client attempts to create to represent the value returned by the server. This option can be very useful when debugging servers as it allows you to see exactly what the server returns.

XML_RPC_Message

This class provides a representation for a request to an XML-RPC server. A client sends an XML_RPC_Message to a server, and receives back an XML_RPC_Response.

Creation

The constructor takes the following form:

$msg = new XML_RPC_Message ( $methodName , $parameterArray )

Where $methodName is a string indicating the name of the method you wish to invoke, and $parameterArray is a simple Array of XML_RPC_Value objects. Here's an example message to the US state name server:

<?php
require_once "XML/RPC.php";
$msg = new XML_RPC_Message("examples.getStateName", array(new XML_RPC_Value(23, "int")));
?>

This example requests the name of state number 23. For more information on XML_RPC_Value objects, see API.

Methods

serialize()

$outString = $msg->serialize ( )

Returns the an XML string representing the XML-RPC message.

addParam()

$msg->addParam ( $xmlrpcVal )

Adds the XML_RPC_Value $xmlrpcVal to the parameter list for this method call.

Returns an XML_RPC_Value object. If the parameter doesn't exist, an XML_RPC_Response object is returned.

getParam()

$xmlrpcVal = $msg->getParam ( $n )

Gets the $nth parameter in the message. Use this method in server implementations. Returns the undef value if no such parameter exists.

getNumParams()

$n = $msg->getNumParams ( )

Returns the number of parameters attached to this message.

method()

$methName=$msg->method ( )

$msg->method ( $methName )

Gets or sets the method contained in the XML-RPC message.

parseResponse()

$response = $msg->parseResponse ( $xmlString )

Given an incoming XML-RPC server response contained in the string $xmlString, this method constructs an XML_RPC_Response response object and returns it, setting error codes as appropriate.

This method processes any HTTP/MIME headers it finds.

parseResponseFile()

$response = $msg->parseResponseFile ( $fileHandle )

Given an incoming XML-RPC server response on the file handle $fileHandle, this method reads the data and passes it to parseResponse().

This method is useful to construct responses from pre-prepared files. It processes any HTTP headers it finds.

XML_RPC_Response

This class is used to contain responses to XML-RPC requests. A server method handler will construct an XML_RPC_Response and pass it as a return value. This same value will be returned by the result of an invocation of the send() method of the XML_RPC_Client class.

Creation

$resp = new XML_RPC_Response ( $xmlrpcval )

$resp = new XML_RPC_Response ( 0 , $errcode , $errstring )

The first instance is used when execution has happened without difficulty: $xmlrpcval is an XML_RPC_Value value with the result of the method execution contained in it.

The second type of constructor is used in case of failure. $errcode and $errstring are used to provide indication of what has gone wrong. See API for more information on passing error codes.

Methods

faultCode()

$fn = $resp->faultCode ( )

Returns the integer fault code return from the XML-RPC response $resp. A zero value indicates success, any other value indicates a failure response.

faultString()

$fs = $resp->faultString ( )

Returns the human readable explanation of the fault indicated by $resp->faultCode.

value()

$xmlrpcVal = $resp->value ( )

Returns an XML_RPC_Value object containing the return value sent by the server. If the response's faultCode is non-zero then the value returned by this method should not be used (it may not even be an object).

serialize()

$outString = $resp->serialize ( )

Returns an XML string representation of the response.

XML_RPC_Value

This is where a lot of the hard work gets done. This class enables the creation and encapsulation of values for XML-RPC.

Ensure you've read the XML-RPC spec at http://www.xmlrpc.com/stories/storyReader$7 before reading on as it will make things clearer.

The XML_RPC_Value class can store arbitrarily complicated values using the following types: i4, int, boolean, string, double, dateTime.iso8601, base64, array or struct. You should refer to the spec for more information on what each of these types mean.

Notes on types

int

The type i4 is accepted as a synonym for int. The value parsing code will always convert i4 to int: int is regarded by this implementation as the canonical name for this type.

base64

Base 64 encoding is performed transparently to the caller when using this type. Therefore you ought to consider it as a binary data type, for use when you want to pass none 7-bit clean data. Decoding is also transparent.

boolean

The values true and 1 map to true. All other values (including the empty string) are converted to false.

string

The characters <, >, " and & are converted to their entity equivalents &lt;, &gt;, &quot; and &amp; for transport through XML-RPC. The current XML-RPC spec recommends only encoding < and & but this implementation goes further, for reasons explained by the XML 1.0 recommendation.

Currently, passing a string "-1" to XML_RPC_Value's constructor creates an empty result since it serves as a special/magic value.

TODO: &apos; entity is not yet supported

Creation

The constructor is the normal way to create an XML_RPC_Value. The constructor can take these forms:

$myVal = new XML_RPC_Value ( )

$myVal = new XML_RPC_Value ( $stringVal )

$myVal = new XML_RPC_Value ( $scalarVal , 'int' | 'boolean' | 'string' | 'double' | 'dateTime.iso8601' | 'base64' )

$myVal = new XML_RPC_Value ( $arrayVal , 'array' | 'struct' )

The first constructor creates an empty value, which must be altered using the methods addScalar(), addArray() or addStruct() before it can be used.

The second constructor creates a simple string value.

The third constructor is used to create a scalar value. The second parameter must be a name of an XML-RPC type. Examples:

<?php
$myInt = new XML_RPC_Value(1267, "int");
$myString= new XML_RPC_Value("Hello, World!", "string");
$myBool = new XML_RPC_Value(1, "boolean");
?>

The fourth constructor form can be used to compose complex XML-RPC values. The first argument is either a simple array in the case of an XML-RPC array or an associative array in the case of a struct. The elements of the array must be XML_RPC_Value objects themselves. Examples:


$myArray = new XML_RPC_Value(array(
    new XML_RPC_Value("Tom"), new XML_RPC_Value("Dick"),
    new XML_RPC_Value("Harry")), "array");

$myStruct = new XML_RPC_Value(array(
    "name" => new XML_RPC_Value("Tom"),
    "age" => new XML_RPC_Value(34, "int"),
    "geek" => new XML_RPC_Value(1, "boolean")), "struct");

Methods

addScalar()

$ok = $val->addScalar ( $stringVal )

$ok = $val->addScalar ( $scalarVal , 'int' | 'boolean' | 'string' | 'double' | 'dateTime.iso8601' | 'base64' )

If $val is an empty XML_RPC_Value this method makes it a scalar value, and sets that value. If $val is already a scalar value, then no more scalars can be added and 0 is returned. If all went OK, 1 is returned.

There is a special case if $val is an array: the scalar value passedis appended to the array.

addArray()

$ok = $val->addArray ( $arrayVal )

Turns an empty XML_RPC_Value into an array with contents as specified by $arrayVal. See the fourth constructor form for more information.

addStruct()

$ok = $val->addStruct ( $assocArrayVal )

Turns an empty XML_RPC_Value into a struct with contents as specified by $assocArrayVal. See the fourth constructor form for more information.

kindOf()

$kind = $val->kindOf ( )

Returns a string containing struct, array or scalar describing the base type of the value. If it returns undef it means that the value hasn't been initialised.

serialize()

$outString = $val->serialize ( )

Returns a string containing the XML-RPC representation of this value.

scalarval()

$scalarVal = $val->scalarval ( )

If $val->kindOf() == 'scalar', this method returns the actual PHP-language value of the scalar (base 64 decoding is automatically handled here).

scalartyp()

$typeName = $val->scalartyp ( )

If $val->kindOf() == 'scalar', this method returns a string denoting the type of the scalar. As mentioned before, i4 is always coerced to int.

arraymem()

$xmlrpcVal = $val->arraymem ( $n )

Returns the $nth element in the array represented by the value $val. The value returned is an XML_RPC_Value object.

arraysize()

$len = $val->arraysize ( )

If $val is an array, returns the number of elements in that array.

structmem()

$xmlrpcVal = $val->structmem ( $memberName )

Returns the element called $memberName from the struct represented by the value $val. The value returned is an XML_RPC_Value object.

structeach()

list($key,$value) = $val->structeach ( )

Returns the next (key,value) pair from the struct, when $val is a struct. See also API.

structreset()

$val->structreset ( )

Resets the internal pointer for structeach() to the beginning of the struct, where $val is a struct.

XML_RPC_Server

The current implementation of this class has been kept as simple as possible. The constructor for the server basically does all the work. Here's a minimal example:

<?php
function foo ($params) {
   ...
}

$s = new XML_RPC_Server(array("examples.myFunc" => array("function" => "foo")));
?>

This performs everything you need to do with a server. The single argument is an associative array from method names to function names. The request is parsed and despatched to the relevant function, which is reponsible for returning a XML_RPC_Response object, which gets serialized back to the caller.

Here is a more detailed look at what the handler function foo() may do:

<?php
function foo ($params) {
    global $XML_RPC_erruser; // import user errcode value

    // $params is the received XML_RPC_Message object.
    if ($err) {
        // this is an error condition
        return new XML_RPC_Response(0, $XML_RPC_erruser+1, // user error 1
           "There's a problem, Captain");
    } else {
        // this is a successful value being returned
        return new XML_RPC_Response(new XML_RPC_Value("All's fine!", "string"));
    }
}
?>

The dispatch map

The first argument to the XML_RPC_Server() constructor is an array, called the dispatch map. In this array is the information the server needs to service the XML-RPC methods you define.

The dispatch map takes the form of an associative array of associative arrays: the outer array has one entry for each method, the key being the method name. The corresponding value is another associative array, which can have the following members:

Method signatures

A signature is a description of a method's return type and its parameter types. A method may have more than one signature.

Within a server's dispatch map, each method has an array of possible signatures. Each signature is an array of types. The first entry is the return type.

Let's run through an example. Imagine you wanted to write a regular PHP function like this:

<?php
function is_8($input, $strict = false) {
    if ($strict) {
       return ($input === 8);
    } else {
       return ($input == 8);
    }
}
?>

To get it to work in an XML_RPC server, you would have to write it like this:

<?php
function is_8($params) {
    // This parameter is required.
    $param = $params->getParam(0);
    if (!XML_RPC_Value::isValue($param)) {
        return $param;
    }
    $input = $param->scalarval();

    // This parameter is optional.
    $param = $params->getParam(1);
    if (!XML_RPC_Value::isValue($param)) {
        $strict = false;
    } else {
        $strict = $param->scalarval();
    }

    if ($strict) {
       $answer = ($input === 8);
    } else {
       $answer = ($input == 8);
    }

    $val = new XML_RPC_Value($answer, 'boolean');
    return new XML_RPC_Response($val);
}
?>

Here is a signature covering all of the possible permutations:

<?php
array(
    array('boolean', 'int'),
    array('boolean', 'int', 'boolean'),
    array('boolean', 'string'),
    array('boolean', 'string', 'boolean'),
)
?>

The server could be instatiated like this:

<?php
$server = new XML_RPC_Server(
    array(
        'isan8' =>
            array(
                'function' => 'is_8',
                'signature' =>
                     array(
                         array('boolean', 'int'),
                         array('boolean', 'int', 'boolean'),
                         array('boolean', 'string'),
                         array('boolean', 'string', 'boolean'),
                     ),
                'docstring' => 'Is the value an 8?'
            ),
    ),
    1,
    0
);
?>

The strings representing the XML-RPC types have been encoded as global variables for your convenience:

<?php
$GLOBALS['XML_RPC_I4']       = 'i4';
$GLOBALS['XML_RPC_Int']      = 'int';
$GLOBALS['XML_RPC_Boolean']  = 'boolean';
$GLOBALS['XML_RPC_Double']   = 'double';
$GLOBALS['XML_RPC_String']   = 'string';
$GLOBALS['XML_RPC_DateTime'] = 'dateTime.iso8601';
$GLOBALS['XML_RPC_Base64']   = 'base64';
$GLOBALS['XML_RPC_Array']    = 'array';
$GLOBALS['XML_RPC_Struct']   = 'struct';
?>

Delaying the server response

You may want to construct the server, but for some reason not fulfill the request immediately (security verification, for instance). If you pass the constructor a second argument of 0 this will have the desired effect. You can then use the service() method of the server class to service the request. For example:

<?php
$s = new XML_RPC_Server($myDispMap, 0);

// ... some code that does other stuff here

$s->service();
?>

Fault reporting

Fault codes for your servers should start at the value indicated by the global $xmlrpcerruser + 1.

Standard errors returned by the server include:

1 Unknown method

Returned if the server was asked to dispatch a method it didn't know about

2 Invalid return payload

This error is actually generated by the client, not server, code, but signifies that a server returned something it couldn't understand.

3 Incorrect parameters

This error is generated when the server has signature(s) defined for a method, and the parameters passed by the client do not match any of signatures.

4 Can't introspect: method unknown

This error is generated by the builtin system.*() methods when any kind of introspection is attempted on a method undefined by the server.

5 Didn't receive 200 OK from remote server

This error is generated by the client when a remote server doesn't return HTTP/1.1 200 OK in response to a request. A more detailed error report is added onto the end of the phrase above.

100- XML parse errors

Returns 100 plus the XML parser error code for the fault that occurred. The faultString returned explains where the parse error was in the incoming XML stream.

XML_RPC_Dump

This class generates string representations of the data in XML_RPC_Value objects.

Other Functions

Below are functions that lay outside the various XML_RPC objects.

XML_RPC_encode()

$rpc = XML_RPC_encode ( $php_val )

Takes native php types and encodes them into XML_RPC PHP object format.

XML_RPC_decode()

$values = XML_RPC_decode ( $XML_RPC_val )

Takes a message in PHP XML_RPC object format and translates it into native PHP types.