Re: XML_RPC for php5
| From: | Sergio Carvalho | Date: | Tue, 28 Sep 2004 18:08:01 +0000 |
| Subject: | Re: XML_RPC for php5 | ||
| References: | 1 | Groups: | php.pear.dev |
| Request: | Send a blank email to pear-dev+get-33578@lists.php.net to get a copy of this message | ||
Great minds think alike :-) I've been trying for a month now to get Stig, who is the current maintainer of XML_RPC, to get a look at my implementation. Its now under production use internally at my employer. It is also meant as a showcase of Exception usage. It's fully documented, and available for integration in PEAR as soon as the method for evolving packages to PHP 5 is defined.
The library is a complete departure from Useful Inc's codebase. BC
compatibility is broken to make it possible the use of PHP5's __call
catchall. With the new version, executing an XML_RPC call is as easy as:
$client = new XML_RPC_Client('http://rpc.example.com/1.0/');
$client->exampleMethod(1,2,'abc');
Encoding and decoding is done automatically, there's no need for all the
low level wrangling Useful Inc's library required. It also leans more
heavily on PHP5's XML abilities, whereas Useful Inc's library
implemented its own XML parser.
You can have a look at the source code here:
http://files.sergiocarvalho.com/2004/XML_RPC/
Examples, namely, are here:
http://files.sergiocarvalho.com/2004/XML_RPC/doc/examples/
A complete tgz of the package is here:
http://files.sergiocarvalho.com/2004/XML_RPC/XML_RPC.tgz
Cheers,
Greg Beaver wrote:
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc
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: 64php driver: 320xmlrpc-epi driver: 68interface: 9 --- TOTAL: 878TOTAL 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
Attachment: [application/pgp-signature] OpenPGP digital signature signature.asc