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
MyXmlRpcClient MyXmlRpcServer MyScalarService MyArrayService MyHtml Entry point HTML | Try it | View source code
Implementation of the client
- We define the XMLRPC types.
class MyXmlRpcClient
{
// We define the XMLRPC types.
public static $types = array(
'AUTO_DETECT_TYPE',
'XMLRPC_TYPE_APACHEI8',
'XMLRPC_TYPE_APACHENIL',
'XMLRPC_TYPE_ARRAY',
'XMLRPC_TYPE_BASE64',
'XMLRPC_TYPE_BOOLEAN',
'XMLRPC_TYPE_DATETIME',
'XMLRPC_TYPE_DOUBLE',
'XMLRPC_TYPE_I4',
'XMLRPC_TYPE_I8',
'XMLRPC_TYPE_INTEGER',
'XMLRPC_TYPE_NIL',
'XMLRPC_TYPE_STRING',
'XMLRPC_TYPE_STRUCT',
// 'XML_STRING',
);
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,
constant("Zend_XmlRpc_Value::$type"));
// 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~', $methods, PREG_GREP_INVERT);
sort($methods);
// We process the request.
switch($action) {
case 'listMethods':
case 'getSignatureForEachMethod':
$result = $client->getIntrospector()->$action();
break;
case '':
$result = 'Enter some data and select an action.';
break;
default:
// We use the proxy server if requested.
if ($proxy) {
list($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($data, $action, $type, $request, $response, $proxy, $methods, $result);
}
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)? 0 : !empty($_GET['request']);
$response = empty($_GET)? 0 : !empty($_GET['response']);
$proxy = empty($_GET)? 0 : !empty($_GET['proxy']);
return array($data, $action, $type, $request, $response, $proxy);
}
Extraction of the data into a scalar or an array.
private function _parseData($data)
{
if (strpos($data, "\n") === false) {
return $data;
} else {
foreach(explode("\n", $data) as $line) {
$parts = explode('=', $line, 2);
if (count($parts) == 1) {
$parsed[] = trim($parts[0]);
} else {
$parsed[trim($parts[0])] = trim($parts[1]);
}
}
return $parsed;
}
}
}
No comments:
Post a Comment