Tuesday, January 26, 2010

Remote services with XML-RPC

In this example, we implement an XML-RPC client and an XML-RPC server. We also use namespaces, the XMLRPC data types, and the server proxy.

Components used in this example
Implementation of the client
  • We define the XMLRPC types.

class MyXmlRpcClient
// We define the XMLRPC types.
public static $types = array(
Processing the user request
  • We get the data, the action, the data type, etc...
  • We parse the data to get a scalar or an array.
  • We convert the data to a given XMLRPC type if requested.
  • We set the server name. It is the same as the client plus one parameter to indicate it is the server.
  • We get the list of remote methods. We remove the system methods.
  • We process the request.
  • We use the proxy server if requested.
  • We add the response details and the request details if needed.
  • If we catch an exception, we return the error message.

    public function process()
// We get the data, the action, the data type, etc...
list($data$action$type$request$response$proxy) = $this->_getParameters();

$methods = array();
        try {
// We parse the data to get a scalar or an array.
$parsed $this->_parseData($data);
// We convert the data to a given XMLRPC type if requested.
$type and $parsed Zend_XmlRpc_Value::getXmlRpcValue($parsed
// We set the server name.
            // It is the same as the client plus one parameter to indicate it is the server.
$server "http://{$_SERVER['HTTP_HOST']}{$_SERVER['PHP_SELF']}?server=";
$client = new Zend_XmlRpc_Client($server);

// We get the list of remote methods. We remove the system methods.
$methods $client->getIntrospector()->listMethods();
$methods preg_grep('~^system~'$methodsPREG_GREP_INVERT);
// We process the request.
switch($action) {
$result $client->getIntrospector()->$action();
$result 'Enter some data and select an action.';
// We use the proxy server if requested.
if ($proxy) {
$service$method) = explode('.'$action);
$server $client->getProxy($service);
$result['PROXY'] = $server->$method($parsed);
                    } else {
$result['CALL'] = $client->call($action, array($parsed));
// We add the response details and the request details if needed.
$response and $result['RESPONSE'] = $client->getLastResponse();
$request and $result['REQUEST'] = $client->getLastRequest();
        } catch (
Exception $e) {
// If we catch an exception, we return the error message.
$result '[' __CLASS__ '] ' $e->getMessage();

        return array(
Extraction of the parameters from the GET request

    private function _getParameters()
$data = isset($_GET['data'])? $_GET['data'] : '';
$action = isset($_GET['action'])? $_GET['action'] : null;
$type = (isset($_GET['type']) and in_array($_GET['type'], self::$types))? 
$_GET['type'] : null;
$request = empty($_GET)? : !empty($_GET['request']);
$response = empty($_GET)? : !empty($_GET['response']);
$proxy = empty($_GET)? : !empty($_GET['proxy']);

        return array(
Extraction of the data into a scalar or an array.

    private function _parseData($data)
        if (
strpos($data"\n") === false) {
        } else {
explode("\n"$data) as $line) {
$parts explode('='$line2);
                if (
count($parts) == 1) {
$parsed[] = trim($parts[0]);
                } else {
$parsed[trim($parts[0])] = trim($parts[1]);


No comments:

Post a Comment