XML-RPC autodiscovery

You probably know by know that I’ve been playing with PEAR and XML-RPC a lot lately. Well when reading an excellent book called Advanced PHP Programming I came across a small section on XML-RPC autodiscovery. This seemed like an interesting thing to me (no, really it did), so I decided to have a play.

Now my only problem with this book is that most of the stuff is written for PHP5. This wouldn’t be so bad (PHP 5 looks to have to great improvements), except for the fact that most of the web servers I have to work on all run PHP 4.

So, for the benefit of the human race, I’ve re-written the script so that it will work in PHP4:

require_once('XML/RPC.php');

$url = parse_url('http://www.oreillynet.com/meerkat/xml-rpc/server.php');
//$url = parse_url('http://www.syndic8.com/xmlrpc.php');
//$url = parse_url('http://www.newsisfree.com/RPC');
//$url = parse_url('http://localhost/index.php');

$cli   = new XML_RPC_Client($url['path'], $url['host']);
$msg   = new XML_RPC_Message('system.listMethods');
$resp = $cli->send($msg);

if($resp->faultCode())
{
   echo "** ERROR **n";
   echo 'Fault Code: ' . $result->faultCode() . "n";
   echo 'Fault Reason: ' . $result->faultString() . "n";
   exit;
}

// get list of methods returned
$methods = XML_RPC_decode($resp->value());

foreach($methods as $method)
{
   print "Method $method:n";

   // get the documentation for this method
   $oDoc = $cli->send(
                      new XML_RPC_Message('system.methodHelp',
                      array( new XML_RPC_Value($method) ))
                      );

   $doc = XML_RPC_decode( $oDoc->value() );

   if($doc)
   {
      print "$docn";
   }
   else
   {
      print "No Docstringn";
   }

   // get the method signatures (if there are any)
   $msg = new XML_RPC_Message('system.methodSignature',
                              array(new XML_RPC_Value($method)));
   $oResp = $cli->send($msg);
   $resp = $oResp->value();

   if($resp->kindOf() == 'array')
   {
      $sigs = XML_RPC_decode($resp);
      for($i = 0; $i < count($sigs); $i++)
      {
         $return = array_shift($sigs[$i]);
         $params = implode(", ", $sigs[$i]);
         print "Signature #$i: $return $method($params)n";
      }
   }
   else
   {
      print "No Signaturen";
   }
   print "n";
}

Save this file as something like rpc-test.php and you can run this from the command line like this:

php -f rpc-test.php

Depending on the server you point it at, you will get output like the following (in this case from Meerkat, O’Reilly Network’s Open Wire Service):

Method meerkat.getChannels:
Returns an array of structs of available RSS channels each with its associated channel Id.
Signature #0: array meerkat.getChannels()

Method meerkat.getCategories:
Returns an array of structs of available Meerkat categories each with its associated category Id.
Signature #0: array meerkat.getCategories()

Method meerkat.getCategoriesBySubstring:
Returns an array of structs of available Meerkat categories each with its associated category Id given a substring to match (case-insensitively).
Signature #0: array meerkat.getCategoriesBySubstring(string)

Method meerkat.getChannelsByCategory:
Returns an array of structs of RSS channels in a particular category (specified by integer category id) each with its associated channel Id.
Signature #0: array meerkat.getChannelsByCategory(int)

Method meerkat.getChannelsBySubstring:
Returns an array of structs of RSS channels in a particular category each with its associated channel Id givena substring to match (case-insensitively).
Signature #0: array meerkat.getChannelsBySubstring(string)

Method meerkat.getItems:
Returns an array of structs of RSS items given a recipe struct.

Search Criteria:
  channel (int) - a channel's numeric id
  category (int) - a category's numeric id
  item (int) - a particular item's numeric id
  search (string) - /a MySQL regular expression/
	time_period (string) - travel back in time; format: #(MINUTE|HOUR|DAY)
  profile (int) - a particular profile's numeric id
  mob (int) - a particular mob's numeric id
  url (string) - a particular url

Display Recipes:
  ids (int) - Return story ids (0=off, 1=on)
  descriptions (int) - Return item descriptions (0=off, 1=full, >1=length)
  categories (int) - Return categories with which items are associated (0=off, 1=on)
  channels (int) - Return channels in which items appeared (0=off, 1=on)
  dates (int) - Return the dates items were picked up by Meerkat (0=off, 1=on)
  num_items (int) - The number of items to be returned (0 < n <=50)

Example:
  $ f = new xmlrpcmsg("meerkat.getItems",
    array(
      new xmlrpcval(
        array(
          "channel" => new xmlrpcval(724, "int"),
          "search" => new xmlrpcval("/xml|[Jj]ava/", "string"),
          "time_period" => new xmlrpcval("3DAY", "string"),
          "ids" => new xmlrpcval(0, "int"),
          "descriptions" => new xmlrpcval(200, "int"),
          "categories" => new xmlrpcval(0, "int"),
          "channels" => new xmlrpcval(0, "int"),
          "dates" => new xmlrpcval(0, "int"),
          "num_items" => new xmlrpcval(5, "int"),
      	),
        "struct"
      )
    )
  );

Signature #0: array meerkat.getItems(struct)

Method system.listMethods:
This method lists all the methods that the XML-RPC server knows how to dispatch
Signature #0: array system.listMethods(string)
Signature #1: array system.listMethods()

Method system.methodHelp:
Returns help text if defined for the method passed, otherwise returns an empty string
Signature #0: string system.methodHelp(string)

Method system.methodSignature:
Returns an array of known signatures (an array of arrays) for the method name passed. If no signatures are known, returns a none-array (test for type != array to detect missing signature)
Signature #0: array system.methodSignature(string)

Caveat

You may run into some problems when running this script: not all servers make the system methods available to them (like system.listMethods, system.methodHelp, and system.methodSignature

Anyway, I hope someone finds this useful/interesting…

Sociable:These icons link to social bookmarking sites where readers can share and discover new web pages.
  • del.icio.us
  • digg
  • Furl
  • NewsVine
  • Reddit
  • YahooMyWeb

Leave a Reply