XML_RPC for php5
| From: | Greg Beaver | Date: | Sat, 18 Sep 2004 06:03:32 +0000 |
| Subject: | XML_RPC for php5 | ||
| Groups: | php.pear.dev | ||
| Request: | Send a blank email to pear-dev+get-33423@lists.php.net to get a copy of this message | ||
Hi,
In a fit of boredom/inspiration last night and tonight, I wrote an XML_RPC Client/Server implementation in PHP5 that can use the xmlrpc extension if available, or direct PHP if not, both transparently.
Line counts:
Client: 147 Server: 270base xml-rpc class: 64
php driver: 320xmlrpc-epi driver: 68
interface: 9
---
TOTAL: 878
TOTAL AT ANY TIME: 560-810
These are prior to commenting.
Basic usage is as follows:
<?php
require_once 'XML/RPC5/Client.php';
$client = new XML_RPC5_Client('http://pear.chiaraquartet.net/xmlrpc.php');
print_r($client->{'system.listMethods'}());
?>
Note that the above syntax allows "." in a method name, as in $obj->{"methodname"}([params]); A call method is available for those who are made queasy by this syntax
$client->call('system.listMethods'[, $param1, $param2, ...]);
You can also extend the class in two ways to automatically define the class, and call methods normally
Option #1:
<?php
require_once 'XML/RPC5/Client.php';
class myclass extends XML_RPC5_Client
{
protected $rpcclass = 'system';} $client = new myclass; print_r($client->listMethods()); ?> Option #2: <?php require_once 'XML/RPC5/Client.php'; class XML_RPC5_Client_system extends XML_RPC5_Client {} $client = new XML_RPC5_Client_system; print_r($client->listMethods()); ?> The server is also easy to use, and supports full introspection. Unlike other generic server implementations, it easily supports multiple classes implementing different XML-RPC classes (one class for all "package.*" methods, one class for all "channel.*"). The best feature is that it automatically pulls introspection data from the class using reflection, and so server setup is something like the following: Option #1 (inheritance): <?php require_once 'XML/RPC5/Server.php'; class MyServer extends XML_RPC5_Server {
/**
* method summary - will be retrievable by introspection
* @param string This comment is ignored by docblock parser
* @param int
* @return array
*/
function someFunc($a, $b = 1)
{
//.....
}
/**
* does something else
* @param array
* @return mixed
*/
function somethingElse($arr)
{
}
}
$server = new MyServer('xmlrpc.php', 'rpcclass');
// handles rpcclass.someFunc, rpcclass.somethingElse
MyServer::run();
?>
Let's say you have a pre-existing class that extends another class, and so you can't make it extend XML_RPC5_Server. No problem! Just use the interface provided, and it will work.
Option #2 (interface):
<?php
require_once 'XML/RPC5/Server.php';
class MyServer extends XML_RPC5_Server implements XML_RPC5_Interface_Server
{
private $_uri;
public function __construct($uri)
{
$this->_uri = $uri;
}
/**
* method summary - will be retrievable by introspection
* @param string This comment is ignored by docblock parser
* @param int
* @return array
*/
function someFunc($a, $b = 1)
{
//.....
}
/**
* does something else
* @param array
* @return mixed
*/
function somethingElse($arr)
{
}
public function getXmlrpcServerMethodMap()
{
// map rpc method names to real methods
return array();
}
public function getXmlrpcServerUri()
{
return $this->_uri;
}
public function getXmlrpcServerClassName()
{
return 'rpcclass';
}
public function getSignatures($rpcclass, $phpclass)
{
return XML_RPC5_Server::getSignatures('rpcclass', $this);
}
}
$server = new MyServer('http://pear.chiaraquartet.net/xmlrpc.php');
XML_RPC5_Server::registerServer($server);
XML_RPC5_Server::run();
?>
The best thing is that basic methods in the interface or the server are ignored when creating the method lists. Also, by putting a "@noxmlrpc" tag anywhere in a docblock, a method will be ignored. Only public methods will be exposed, obviously.
So, then the question is raised - what does PEAR want to do, assuming the code is liked? Should I propose XML_RPC5 through PEPr? Or just keep it off-pear in my chiara channel? I will be using it in Chiara_Server to cut LOADS of code away from the xml-rpc stuff and remove the xmlrpc extension dep. It would also be wonderful for PEAR2, but that is a long ways off.
Needless to say, this is a pure php5-only implementation (I might enter it in the Zend contest, who knows) that uses lots of php5-only features (__call(), reflection, exceptions, interfaces, PPP, simplexml), and can't be backported at all.
Greg