18.2. Zend_XmlRpc_Client

18.2.1. Introduction

Using the Zend_XmlRpc_Client is very similar to using SoapClient objects (SOAP web service extension). You can simply call the XML-RPC service procedures as Zend_XmlRpc_Client methods. Specify the service's full address in the Zend_XmlRpc_Client constructor.

Example 18.1. A basic XML-RPC request

<?php
/**
 * Connect to framework.zend.com server and an array describing
 * the methods available.
 */
require_once 'Zend/XmlRpc/Client.php';

$server = new Zend_XmlRpc_Client('http://framework.zend.com/xmlrpc');

print_r( $server->system->listMethods() );

?>
            

[Note] Note
Zend_XmlRpc_Client attempts to make remote methods look as much like native methods as possible. If a remote method contains namespaces, such as system.listMethods() above, the call is made using object chaining in PHP: $server->system->listMethods().

18.2.2. Using parameters

Some XML-RPC service procedures require parameters, the necessary parameters are passed as parameters for the Zend_XmlRpc_Client method. XML-RPC procedure parameters must be a specific XML-RPC type. Parameters can be passed in 2 ways: as PHP natives or Zend_XmlRpc_Value objects which represent XML-RPC types.

18.2.2.1. Passing PHP native variables as parameters

Parameters passed as native PHP variables, meaning as a string, integer, float, boolean, array or an object. In this case, each PHP native type will be auto-detected and converted into one of the XML-RPC types according to this table:

Table 18.1. PHP native values convertion to XML-RPC types

PHP native type XML-RPC type
integer int
double double
boolean boolean
string string
array array
associative array struct
object array
...
/** 2 parameters are passed in this procedure
 *  The first parameter is a string that will be auto-converted into an XML-RPC string type
 *  The second parameter is an associative array that will be converted into an XML-RPC struct 
 */

$p1 = 'parameter 1';
$p2 = array('name' => 'Joe', 'age' => 30);

$service->serviceProcedure($p1, $p2);
...
            

18.2.2.2. Passing Zend_XmlRpc_Value objects as parameters

Parameters passed as Zend_XmlRpc_Value objects. You can create one of the Zend_XmlRpc_Value instances to specify the exact XML-RPC type of your parameters. The main reasons for explictly specifing the XML-RPC types are:

  • When you want to make sure the correct parameter type is passed to the procedure (i.e. the procedure requires an integer and you may receive the parameter from the $_GET array as a string)
  • When the procedure requires base64 or dateTime.iso8601 type (which doesn't exists as a PHP native type)
  • When auto-convertion may fail (i.e. you want to pass an empty XML-RPC struct as a parameter. Empty structs are represented as empty arrays in PHP but, if you give an empty array as a parameter it will be auto-converted to an XML-RPC array since it's not an associative array)

There are 2 ways to create an Zend_XmlRpc_Value object: the explicit way (call the object's constructor) or using the Zend_XmlRpc_Value::getXmlRpcValue() static function with the required XML-RPC type constant.

Table 18.2. Zend_XmlRpc_Value object representing the XML-RPC types

XML-RPC type Matching Zend_XmlRpc_Value constant Zend_XmlRpc_Value object
int Zend_XmlRpc_Value::XMLRPC_TYPE_INTEGER Zend_XmlRpc_Value_Integer
double Zend_XmlRpc_Value::XMLRPC_TYPE_DOUBLE Zend_XmlRpc_Value_Double
boolean Zend_XmlRpc_Value::XMLRPC_TYPE_BOOLEAN Zend_XmlRpc_Value_Boolean
string Zend_XmlRpc_Value::XMLRPC_TYPE_STRING Zend_XmlRpc_Value_String
base64 Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64 Zend_XmlRpc_Value_Base64
dateTime.iso8601 Zend_XmlRpc_Value::XMLRPC_TYPE_DATETIME Zend_XmlRpc_Value_DateTime
array Zend_XmlRpc_Value::XMLRPC_TYPE_ARRAY Zend_XmlRpc_Value_Array
struct Zend_XmlRpc_Value::XMLRPC_TYPE_STRUCT Zend_XmlRpc_Value_Struct
...
/** 2 parameters are passed to this procedure
 *  The first parameter is an XML-RPC base64 type that is created using the static Zend_XmlRpc_Value::getXmlRpcValue() function
 *  The second parameter is an XML-RPC structure that is created explictly
 */

$p1 = ZXmlRpcValue::getXmlRpcValue('encoded string', Zend_XmlRpc_Value::XMLRPC_TYPE_BASE64);
$p2 = new Zend_XmlRpc_Value_Struct(array('name' => 'Joe', 'age' => 30));

$service->serviceProcedure($p1, $p2);
...
            

[Note] Note
The value of the parameter is still given in a PHP variable but will be converted to the specified type using PHP conversion techniques (i.e. if a string is given as a value to the Zend_XmlRpc_Value_Integer object, it will be converted using (int)$value).

18.2.2.3. Parse an XML string into XML-RPC parameter

This method of passing parameters is used internaly in the Zend_XmlRpc package and it's not recommended.

If you still need to use this method, you should use the Zend_XmlRpc_Value::getXmlRpcValue() static function to parse an XML string into a Zend_XmlRpc_Value object which represents the corresponding XML-RPC type. The Zend_XmlRpc_Value::getXmlRpcValue() function should receive 2 parameters: the XML string and the Zend_XmlRpc_Value::XML_STRING constant.

18.2.3. Type hinting of parameters

The main difference between the XML-RPC and SOAP web services is the WSDL file. The SOAP protocol usualy has a WSDL file that describes the interface to the web service. According to this interface, the SOAP client knows what are the necessary parameter types it has to send to the server and what is the return value type. Without the WSDL file, the user might have a problem knowing these types.

The XML-RPC protocol solution uses a special procedure of the service called system.methodSignature. This procedure gets a procedure name as a parameter and returns the signature of the given procedure. The signature is the necessary parameter's type and return value type of that procedure.

[Note] Note
Not all XML-RPC servers support the special system.methodSignature procedure, servers who don't support it cannot support type hinting.

The Zend_XmlRpc_Client implements a sort of 'WSDL' type file for XML-RPC servers using the system.methodSignature procedure. If requested, the Zend_XmlRpc_Client will request a list of all the procedures of an XML-RPC server, request all the signatures of those procedures, and keep all this data in an XML file (similar to the SOAP WSDL file). When using the same XML-RPC server again, the user can supply the XML file and the Zend_XmlRpc_Client will type hint all the parameters for the requested procedure according to their signatures.

The procedures signatures XML file is created by calling the Zend_XmlRpc_Client::__getMethodsXml() function (the function returns an XML string containing all the signature's data). To set an existing signatures XML file, the user can pass the XML data as a parameter in the Zend_XmlRpc_Client constructor or call the Zend_XmlRpc_Client::__setMethodsXml() function.

Example 18.2. Calling an XML-RPC service with type hinting

<?php
/**
 * Connect to an XML-RPC server, and save it's signatures file (the XML-RPC eqvivilant to a SOAP WSDL file)
 */
require_once 'Zend/XmlRpc/Client.php';

$service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc');

file_put_contents('/tmp/xmlrpc-signatures/example.xml', $service->__getMethodsXml());

/* The $service object contains all the signatures of the XML-RPC server,
    when the serviceProcedure is called, its parameter ($param) is converted
    to the necessary type according to the procedure's signature.
 */
$service->serviceProcedure($param);
?>
            
<?php
/**
 * Connect to an XML-RPC server, using an existing signature file, we make sure
 * that the type of the parameters passed to the procedures are of the necessary type
 */
require_once 'Zend/XmlRpc/Client.php';

$signature_file_xml = file_get_contents('/tmp/xmlrpc-signatures/example.xml');
$service = new Zend_XmlRpc_Client('http://www.example.org/xmlrpc', 'namespace', $signature_file_xml);

/* The $service object contains all the signatures of the XML-RPC server,
    when the serviceProcedure is called, its parameter ($param) is converted
    to the necessary type according to the procedure's signature.
 */
$service->serviceProcedure($param);
?>
            

18.2.4. Getting the response

The XML-RPC procedure returns a value in an XML-RPC type. The Zend_XmlRpc_Client method which calls the XML-RPC procedure returns a PHP native type that was converted from the returned XML-RPC type.

You can use the Zend_XmlRpc_Client::__getResponse() function to retrieve the return value of the requested procedure. The __getResponse() function receives a parameter which indicates the type of the return value. The response options are:

  • Zend_XmlRpc_Client::RESPONSE_PHP_NATIVE - Return the procedure return value as a PHP native type (convert the XML-RPC type into a PHP type).
  • Zend_XmlRpc_Client::RESPONSE_XML_STRING - Return the XML string representation of the XML-RPC response.
  • Zend_XmlRpc_Client::RESPONSE_ZXMLRPC_OBJECT - Return a Zend_XmlRpc_Value object which represents the returned XML-RPC type.

...
$service->serviceProcedure();

$response = $service->__getResponse();
// $response is the PHP variable converted from the XML-RPC type return value
  
$response = $service->__getResponse(ZXmlRpcClient::RESPONSE_XML_STRING);
// $response is a string containing the XML representing the procedure return value

$response = $service->__getResponse(ZXmlRpcClient::RESPONSE_ZXMLRPC_OBJECT);
// $response is a Zend_XmlRpc_Value instance representing the XML-RPC type return value
...