XML-RPC is a "standard" (well, not yet exactly) for accessing remotely provided 'Web services'. More exactly it is just a complicated encoding standard for calling functions and procedures on a remote Web server (and getting its calculation or data request results of course). It is still in wide use for many interesting features like accessing database content, searching, data conversion, and so on. It started as a lightweight alternative to SOAP, which currently is more on the rise. While SOAP is much more bloated, also XML-RPC is not the quickest RPC format available, is not really standards-compliant (bogus specs over the time), and so has probably only a limited lifetime now. Therefore you should try to provide your services and access others` via vanilla HTTP requests (form or url encoding), when possible; use the "http.php" class for this. (There is also a faster PHP-RPC standard on the rise, which provides type-safe data transport over compressed and fast connections, without the encoding overhead and charset issues when using XML-RPC.) xmlrpc.php ŻŻŻŻŻŻŻŻŻŻ The 'xmlrpc.php' script implements the XML-RPC spec., but adds a few extensions, namely use of the (yet unregistered) "application/rpc+xml" MIME type and compressed HTTP transportation. It uses a builtin stupid XML parser (for the highly simplified XML-RPC message content) and thus is totally independent of any PHP extensions. It of course takes advantage of the XML extension where present (a lot faster), and it even can make use of Epinions XML-RPC extension for PHP (really fast than). It is mostly not object-oriented, but extremely easy to use for building XML-RPC servers or calling remote procedures. configuration ŻŻŻŻŻŻŻŻŻŻŻŻŻ There are a few constants and variables that the 'xmlrpc.php' script respects. XMLRPC_PLUS If set to 1 enables use of the "application/rpc+xml" MIME type and request compression per default (for server and client). In 2004 still not the recommended setting. XMLRPC_AUTO_TYPES Allows the request encoder to automatically determine the and types, even if you just used them as scalar PHP values. Otherwise you had to use 'new xmlrpc_base64("STrinG==")' and 'new xmlrpc_datetime("20001020T00:00:00")' to prepare such values. XMLRPC_AUTO_UTF8 Takes care of transforming the complete RPC messages into/from UTF-8, what is useful if your scripts deal only with Latin1 and always expect this. are also de/encoded if you set this constant to 2. XMLRPC_CHARSET The whole script is currently optimized to produce UTF-8 and decode requests from/into Latin-1 for your scripts. XMLRPC_FAST Enables use of Epinions XML-RPC extension module for PHP automatically where available. You only want to disable this for debugging purposes. XMLRPC_OO Engages error result objects, else you had to use the two global vars "$xmlrpc_error" and "$xmlrpc_errorstr" to detect such cases. If you enable it you must however compare all xmlrpc_request() result values against being an object (what does not happen for succeeded XML-RPC requests). XMLRPC_AUTODISCOVERY If you create a "xmlrpc" or "xmlrpc_connection" object and this is enabled, you would get the object with function names of the automatically instantiated methods of the remotely provided service wrapped into one object (not yet), much like in the Python library for xmlrpc. XMLRPC_LOG Creates a log file for incoming requests to the _server() part of xmlrpc (whenerver you activate it with the _server() call). There are also a few automatically defined values, which you shouldn't care about: XMLRPC_MIME Contains the currently selected default MIME type for transport. XMLRPC_MIME_NEW Contains the newer MIME type value. Do not change. XMLRPC_MIME_OLD For compatibility with older XML-RPC clients and servers. Do not change. XMLRPC_ACCEPT Again the MIME Types wrapped into a HTTP Accept: header for requests and responses. XMLRPC_EPI Tells if the Epinions extension is available. server configuration ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ $xmlrpc_methods[] Every accessible method (for remote calls) must be defined here, for use with the xmlrpc_server(). There is a separate section on this one. making xmlrpc() requests ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ You can call a remote procedure by just using the short xmlrpc() call syntax: $result = xmlrpc("http://example.com/rpc.php", "the.function", 1, 2, 3); Where 1, 2 and 3 would be parameters to "the.function" on the remote server. The number of parameters is not limited, and you do not need to give one at all (if the remote procedure does not require them. The parameter values are automatically encoded into XML-RPC representations except for and ones, for which you needed to create objects first. The $result of course recieved in ordinary PHP representation of the remote functions result value. xmlrpc_request() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Is basically the same as calling the xmlrpc() function, but that all parameters given to the remote function are now to be passed as array in the third parameter: $params = array( "param1", "param2", "param3" ); $r = xmlrpc_request("server.com:80", "remoteMethod", $params); Also a fourth parameter to xmlrpc_request (boolean) says if to use the old XML-RPC or the faster XML+RPC interface. But beware, that this could fail if you connect to an older server. xmlrpc_connection ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ You can also establish a 'connection' (this is purely virtual) to a remote XML-RPC server, using a xmlrpc_connection object as follows: $xc = new xmlrpc_connection("http://example.com/rpc.php"); Then you could regularily call remote functions on that server: $result1 = $xc->call("function1"); $result2 = $xc->call("function2", 2, $result1, 0x5F02); The xmlrpc_connection automatically chooses XML+RPC if available with the remote server. data types ŻŻŻŻŻŻŻŻŻŻ Unless XMLRPC_AUTO_TYPES was enabled (discouraged, because this is considered 'unreliable type guessing') you need to explicetely mark parameters passed to the xmlrpc() or xmlrpc_request() calls for their later XML-RPC type. To do so, you have the two class types 'xmlrpc_datetime' and 'xmlrpc_base64' availabe. Use them as follows: $param1 = new xmlrpc_base64( base64_encode($string1) ); $p2 = new xmlrpc_datetime( time() + 60*60*24*7 ); $r = xmlrpc("www.server.com/rpc/", "function1", $param1, $p2); Please note, that you needed to call base64_encode() yourself, and that the _datetime() can also use standard Unix timestamps as input. The XML-RPC entites are, btw, automatically converted into Unix timestamps, if returned as result from xmlrpc() and xmlrpc_request() calls. This happens regardless of XMLRPC_AUTO_TYPES. If XMLRPC_AUTO_TYPES is set to 2, then even result values would be automatically converted into their plain (binary) string representation. "Bugs" ŻŻŻŻŻŻ pass-by-reference is not possible ;) xmlrpc_server() use ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ To make a set of functions available for remote calls, you would create an interface script and make its URL public. Assuming that you had a subdirectory "./myrpc" on your server, you would likely want to create the file "./myrpc/index.php" with following content: So, by calling the xmlrpc_server() you make all registered functions ($xmlrpc_methods) available with the URL "xml+rpc://example.com/myrpc/" for remote calls. $xmlrpc_methods[] ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ All function names you list in this array (before calling the xmlrpc_server() function) will be available for remote calls. The function names are mapped to remote method names by having the _ underscore as alias the the . dot, which is commonly used. So a function whose name was "tools_register" was available as remotely callable method "tools_register" or "tools.register". Also with xmlrpc_server() it is possible to register member methods of object classes as remotely callable methods. All you needed to do is list your class in $xmlrpc_methods[]. You can also give aliases, both for function names and for object classes: $xmlrpc_methods["callable.methodname"] = "here_function_name"; $xmlrpc_methods["section"] = "here_class_name"; The member methods of a class cannot be aliased however. xmlrpc_server() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Just fetches the current request, decodes it and executes the destination method (PHP function) if listed in the global $xmlrpc_methods[] variable. It automatically exits after sending the response or an error. So this is the last command in your xmlrpc wrapper script. xmlrpc_fetch_post_chunk() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Begs PHP for the complete POST data stream. It only has two options to do so and may fail with some Webservers and earlier PHP versions. In either case try to set the "always_populate_raw_post_data" option in php.ini or from within a .htaccess file. To allow the server part to receive the XML-RPC message, you either need PHP 4.3 or later, or configure your PHP interpreter specifically to pass in the POSTed data stream. In you php.ini ([PHP] section) add: always_populate_raw_post_data = 1 Or following in a .htaccess per-dir configuration file for Apache: php_option always_populate_raw_post_data=1 xmlrpc_send_response() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Is called from within xmlrpc_server() to send the response for the processed request (also sends error responses). xmlrpc_error() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Creates a XML-RPC error result array. --------------------------------------------------------------------------- internals --------------------------------------------------------------------------- Unless you are interrested in an in-deep discussion of the "xmlrpc.php" you should effectively stop reading here. xmlrpc data representation encoders ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ This lib uses the simple xml2array() compact format to do the initial work of converting a XML file into an array representation. Various design restrictions of the XML-RPC message format then impose certain structures inside of the xml2array-compact representation, what is taken adavantage of. For example entries have in the compact representation sub-elements like ["member,0"], ["member,1"], ["member,2"] and so on. Each of which then has two sub elements: ["name,0"] and ["value,1"]. The XML-RPC instead had one ["data,0"] with sub-arrays of ["value,0"], ["value,1"], ["value,2"] and so on, which would be recursively feed through: xmlrpc_decode_value() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Makes a PHP representation of a part (one must start it with the content of a ["value,0"]) from a xml2array()-compact representation made out of a XML-RPC message. xmlrpc_compact_value() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Converts a PHP array or scalar variable into an array suitable for transformation into a XML-RPC message string using the array2xml() function then. generic functions ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ The xml2array() and array2xml() functions are stupid XML parsers and probably only suitable for XML-RPC messages. xml2array() ŻŻŻŻŻŻŻŻŻŻŻ Can decode a SimplifiedXML document into an array structure - and this in two formats. Internall xml+rpc uses only the so called "$compact format". If we had a XML document like the following: String String2 5 It would return for the $compact=1 format, something like: array( "xml,0" => array( "more,0" => array( "string,0" = array( ",0" => " String " ) ) "more,1" => array( "string,0" = array( ",0" => " String2 " ), "int,1" = array( ",0" => 5 ) ) ) ); Where every tagname had a ","+NUMBER suffix, and text nodes would start with the comma. The numbers are always counted up in each nesting level from 0, regardless if it counted text or tag nodes. The not-compact format would hold another subarray to denote a deeper level tag node, but leave the text nodes as entries into the ordering array level. This was more suitable for XML like files, where you had mixed text and tag nodes in a level. For example: string1 string2 Would become in the not-compact format: array( 0 => array( "html" => array( 0 => "\n string1\n " 1 => array( "b" => array( 0 => "string2", ) ) ) ) array2xml() ŻŻŻŻŻŻŻŻŻŻŻ Regenerates a XML stream from an array structure like the one emitted by xml2array(). other functions ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ If you want a different behaviour, you might want to alter one of the following functions. xmlrpc_method_call() ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ Is responsible in the _server() part for invoking the requested function. It does so by using the $xmlrpc_methods[] array as mapping to the PHP functions to activate. If you would like to have a better mapping support, or even to add parameter type and number checking, then this is where you would want to start editing the code.