In this article I will explain how to write an XML-RPC server and client in PHP.
To be able to understand the article, you have to have some idea about XML-RPC in general.
If you feel like gleaning more information about XML-RPC visit the following websites:
http://www.xmlrpc.com/
http://en.wikipedia.org/wiki/XML-RPC
For an introduction to XML-RPC in PHP visit Introduction to XML-RPC In PHP
In this example, we are going to use PHP's XML-RPC extension. Although the extension is considered experimental, it works well.
You distribute applications that are installed on Intranet web servers. The customer might not have public static IP address. Every time you get a call to fix something you have to first determine their IP address manually and then SSH into their server. You dislike services like DynDNS.
You decide to write an XML-RPC server which you can host yourself. You package the XML-RPC client with your application. The next time you get a call from the customer to fix something, you ask them to click on a button. The button runs your XML-RPC client program and updates its IP address to the server. Your server notifies you when this event occurs.
Once you have a basic client and server implementations you can do lot of cool things like application automatically updating itself, notifying the application administrator based on information retrieved from the server, etc.
Our request XML looks like this:
<?xml version="1.0" encoding="iso-8859-1"?> <methodCall> <methodName>my_ip_address</methodName> <params> <param> <value> <string>username</string> </value> </param> <param> <value> <string>password</string> </value> </param> </params> </methodCall>
We send the username and password as the parameters. The remote procedure we wish to call is my_ip_address.
Our response XML looks like this:
<?xml version="1.0" encoding="iso-8859-1"?> <methodResponse> <params> <param> <value> <string>127.0.0.1</string> </value> </param> </params> </methodResponse>
The server returns client's IP address as a string value.
Let's proceed to implement the server. Let us assume your server URL is http://example.com/servies/xmlrpc/ipaddress.php. In the following section we discuss the contents of the script ipaddress.php.
<?php
$xmlrpc_server = xmlrpc_server_create();
xmlrpc_server_register_method($xmlrpc_server, "my_ip_address", "my_ip_address");
?>As the name suggests, xmlrpc_server_create() creates an XML-RPC server. You can register your functions with the XML-RPC server. The second line in the above snippet registers the function "my_ip_address" with the server.
We use the PHP's header() function to set the correct content type.
<?php
header('Content-Type: text/xml');
?>The easiest way to read an XML-RPC request is through the input stream. In the next step we pass the request XML to xmlrpc_server_call_method and print the output.
<?php
$request_xml = file_get_contents("php://input");
print xmlrpc_server_call_method($xmlrpc_server, $request_xml, array());
?>Finally we write the function my_ip_address() we registered with the server. The method arguments sent in the request XML will be available to your function through the second parameter. $args is an array of request method arguments.
<?php
function my_ip_address($method_name, $args, $app_data) {
$username = $args[0];
$password = $args[1];
/**
* Perform authentication and authorization here
* If failed return a fault code or exit
*/
/**
* We just return the client's IP address
*/
return $_SERVER['REMOTE_ADDR'];
}
?>We have completed writing the code for the XML-RPC server implementation. Let us now proceed to the client.
The PHP function xmlrpc_encode_request() helps form the request XML.
<?php
$request = xmlrpc_encode_request("my_ip_address", array('username', 'password'));
?>We create the request XML. The request XML now contains the methodName "my_ip_address" with two string parameter values 'username' and 'password'.
With the help of context stream we make the XML-RPC call.
<?php
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml\r\nUser-Agent: PHPRPC/1.0\r\n",
'content' => $request
)));
/**
* This URL does not exist. Replace it with your server URL
*/
$server = 'http://example.com/servies/xmlrpc/ipaddress.php';
$file = file_get_contents($server, false, $context);
?>The response XML is now stored in $file variable. The XML-RPC extension provides the function xmlrpc_decode() using which we can conveniently retrieve the IP address in our example.
<?php
$response = xmlrpc_decode($file);
echo "My IP Address is " . $response;
?>We have now completed writing both the server and the client.
Here's a sample output.
[sudheer@localhost findip]$ php client.php My IP Address is 132.162.17.240[sudheer@localhost findip]$
You can grab the code from Code Album github repository.
I have posted the contents of both server and client below.
Server - ipaddress.php
<?php
$request_xml = file_get_contents("php://input");
function my_ip_address($method_name, $args, $app_data) {
$username = $args[0];
$password = $args[1];
/**
* Perform authentication and authorization here
* If failed return a fault code or exit
*/
return $_SERVER['REMOTE_ADDR'];
}
$xmlrpc_server = xmlrpc_server_create();
xmlrpc_server_register_method($xmlrpc_server, "my_ip_address", "my_ip_address");
header('Content-Type: text/xml');
print xmlrpc_server_call_method($xmlrpc_server, $request_xml, array());
?>Client.php
<?php
$request = xmlrpc_encode_request("my_ip_address", array('username', 'password'));
$context = stream_context_create(array('http' => array(
'method' => "POST",
'header' => "Content-Type: text/xml\r\nUser-Agent: PHPRPC/1.0\r\n",
'content' => $request
)));
/**
* This URL does not exist. Replace it with your server URL
*/
$server = 'http://codealbumweb.example.com/findip/service.php';
$file = file_get_contents($server, false, $context);
$response = xmlrpc_decode($file);
echo "My IP Address is " . $response;
?>Useful links:
Tell us how you use or intend to use XML-RPC to solve the problems you often encounter.
Thanks
Thanks
Post new comment