XML_RPC for php5

From: 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:             270
base xml-rpc class: 64
php driver:         320
xmlrpc-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

« previous php.pear.dev (#33423) next »