How-To: Learning PHP XML-RPC

How-To: Learning PHP XML-RPC

This post is inspired by a friend’s recent project on web service.

SOAP is the W3C standard for web services. However, as a friend pointed out, XML-RPC is a better alternative for simple implementations.. for starters as well. XML-RPC is a remote procedure call which uses XML for encoding. You can google tons of tutorials on the subject so i will not deal much with it. Some useful sites are the XMLRPC Homepage and the Build Your Own Web Service Using XML-RPC by Sitepoint.

If you can sit comfortably with PHP, a library implementation of XML-RPC protocol written in PHP (read: PHPXMLRPC) is your gateway to web services. The ff. steps documents my learning experience in learning PHPXMLRPC (with a lot of help from my tutor):

–Before we proceed with coding, here are the basic stuff —

1. Download the latest stable release (currently at 2.1 as of August 28) from sourceforge to your server.

2. Decompress to your main web directory: /var/www/html/.

3. Copy the contents of xmlrpc-x.x/lib/ to your php’s include _path.

— Learn the client environment —

4. Open a browser. Go to path-to-xmlrpc/doc/ch11s01.html to view an xml-rpc client example.

5. Copy the example and save anywhere in your web directory. I made a folder test and saved the file as client_state.php. Remember to include xmlrpc.inc and xmlrpcs.inc using the require_once(“…”) php function.

6. Using the example, you can study the important classes used for the client – such as xmlrpcval, xmlrpcmsg and xmlrpc_client – together with their corresponding methods – send, scalarval, serialize, faultCode, and faultString. Use the documentation to find out the functions of each. You can try to make a client at this point.

$msg = new xmlrpcmsg(‘methodName’,array(new xmlrpcval($input, “inputType”)));

$client = new xmlrpc_client(“server_path”, “server_address”, server_port);

— A showcase of the client-server interaction —

7. The easiest way to test a server is through the debugger. On a browser, open path-to-xmlrpc/debugger.

8. Fill in the address, port, and path fields using the parameters in the line with xmlrpc_client from the sample code. Select “List available methods” then press Execute to see the available methods in the server.

9. Click “Describe” beside examples.getStateName. You will see a description of what the method does, its expected inputs and outputs.

10. Click “Load Method Synopsis.” This is the XML payload that the client passes to the server. (Note that the sample code above does the same thing.) Enter a value between <int> and </int>. You can use the value of $stateNum in the sample code to verify.

11. Click “Execute.” The return payload/response should be displayed in the lower frame. An error in the server will commonly result in an “invalid return payload warning” (however, it’s not restricted to that error message). You can play with other methods to get you familiar. The methods with system in its name are built-in methods in all xmlrpc servers.

— Now, for the server part —

12. Now that you have a feel of both client and server, it is time to code for the server part. XMLRPC provides a sample code under demo/server/ folder. View server.php in a vi editor. The length of the code may be overwhelming at first. Don’t try to understand them. Just proceed to the bottom most portion of the code.

13. Check out only the relevant parts first (i.e. what you need for examples.getStateName). The important classes are xmlrpc_server with its service and setDebug methods. These are found at the bottom – everything from $s= new xmlrpc_server(“..”) down to $s->service. You also need the first element of the associative array $a (the contents, also in array form, of the index examples.getStateName). Finally, the function findStateName, and the variables findStateName_sig and findStateName_doc. It’s important to note the structure of array $a and its parameters:

$a = array(“methodName”=>array(“function”=>”functionName”, \ “signature”=>$functionName_sig,”docstring”=>$functionName_doc)

$functionName_sig = array(array(outputType, inputType, […]));

*methodName is what the client sees. functionName is what you use in the server. For simplicity, you can use the same name for both.

*functionName_doc gives a description of the method.

*functionName_sig shows the input and output types.

*Type can be Array ($xmlrpcArray), String ($xmlrpcString), and integer ($xmlrpcInt). [I think there are more types, but i only know these three atm].

14. Use the debugger. Point the address and path to your own server. This works just like steps 9-11, except that this time, it uses the web service you provide.

15. Following the sample server code, you should be ready to make your own server.php. Think of a simple service (such as a function that returns the value of the factorial given an integer input) that you can implement. Place the file in the folder test and name it as xmlrpcserver.php. Remember to include the relevant parts stated in Step 13. Also include xmlrpc.inc and xmlrpcs.inc in your code using require_once(“..”).

16. That should do it. You may test your server using the debugger or by using a client.

17. Set $server->setDebug(“2”) to view debugging information in the client. This is very helpful since it’s difficult to find the exact error when you only see a generic faultCode.

There! You’re done. The next step is to try using arrays as output (such as database information given a studentName). I had a hard time with this part. Read more on the 4th xmlrpcval constructor type, simple array in the case of an XML-RPC array or an associative array in the case of a struct. Note that the elements of the array must be xmlrpcval objects themselves. For a general array return payload, the ff. code can be used:

$param = new xmlrpcval(
array(
“A” => new xmlrpcval($row[“a”], ‘string’),
“B” => new xmlrpcval($row[“b”],”string”),
),”struct”);
return new xmlrpcresp($param);

If it can’t be avoided to add new rows to your array, you need addStruct or addArray.

$param1= array(“A” => new xmlrpcval($row[“a”], ‘string’));
$retval = new xmlrpcval();
$retval->addStruct($param1);
$param2 = array(“B” => new xmlrpcval($row[“b”],”int”));
$retval->addStruct($param2);
return new xmlrpcresp($retval);

There you go. I hope this helps… Again, it’s always important to read the manual. But for a start, don’t try to digest everything, just pick up the good ones. 🙂 Or better yet, ask for help, just what i did. 😀

Comments are closed.