Simple PHP XMLRPC
28 Feb 2004
My mail management system (currently codenamed NVMS) is in the backend managing userdb, and the web interface is currently written in PHP. XML-RPC seemed the sensible thing to use, as it is simple and portable, Python and Twisted has excellent and easy-to-use support, and I knew PHP could do it. (Well, not without getting sidetracked to determine which XML-RPC library to use for PHP.) I settled on PEAR's XML_RPC. It's nowhere near as braindeadly simple and nice as Python's xmlrpclib (and Twisted's XML-RPC server support), so here's something I used to make PEAR's XML_RPC slightly easier to work with, and an example of how it works on the other side with Twisted.
<?php
require_once('XML/RPC.php');
class NVMSXmlrpc {
function sendMsg($method) {
global $_VNMS_Xmlrpc_client;
$args = array_slice(func_get_args(), 1);
if (count($args) === 0) {
$m = new XML_RPC_Message($method);
} else {
$de = array();
foreach($args as $arg) {
$de[] = XML_RPC_encode($arg);
}
//$de = array(XML_RPC_encode($args));
// var_dump($de);
$m = new XML_RPC_Message($method, $de);
}
$resp = $_VNMS_Xmlrpc_client->send($m);
if ($resp->faultCode()) {
return PEAR::raiseError('Fault ' . $resp->faultCode() . ': ' . $resp->faultString());
} else {
return XML_RPC_decode($resp->value());
}
}
}
$_VNMS_Xmlrpc_client = new XML_RPC_Client('/', 'localhost', 9680);
?>
Here's a simple example:
<?php
require_once('nvms.xmlrpc.php');
var_dump(NVMSXmlrpc::sendMsg('test2', array('foo', 'bar'), 3));
?>
This example can talk to a simple Twisted XML-RPC server (way too easy...):
#!/usr/bin/env python
import sys
from twisted.web import server, xmlrpc
from twisted.application import internet
from twisted.internet import reactor
class Example(xmlrpc.XMLRPC):
def xmlrpc_test2(self, arg1, arg2):
return ['s', arg1, 's', arg2, 's']
def main(argv = sys.argv):
w = server.Site(Example())
internet.TCPServer(9680, w, interface='127.0.0.1')
reactor.run()
if __name__ == '__main__':
main()
The output of the PHP tester is:
array(5) {
[0]=>
string(1) "s"
[1]=>
array(2) {
[1]=>
string(3) "bar"
[0]=>
string(3) "foo"
}
[2]=>
string(1) "s"
[3]=>
int(3)
[4]=>
string(1) "s"
}