Home >Backend Development >PHP Tutorial >Using XML technology to construct remote services in PHP (Part 2)_PHP Tutorial
4. Web services based on XML_RPC
It is very convenient to use XML_RPC to construct and use services. Enterprises deploy XML_RPC servers for various services they provide, and users, client software, and client enterprises can use this service to construct high-end services or applications for end users. This competition to provide more effective, cheap and high-quality services will greatly improve the quality of application services.
But there are still some problems to be solved, such as how to catalog, index, and search services on the Web? UDDI attempts to solve this problem, but the standard is not simple, and the industry's response to it is unclear. However, applying XML_RPC within the enterprise will not only improve code reusability, but also bring about a new distributed computing model that will become an important wealth of knowledge in the coming years. The development of XML_RPC started from solving distributed computing problems and becoming the basic level of the serviced Web, thus getting a very good start, which will surely be followed by people's enthusiasm for this standard. That being the case, let us now take a look at the practical application of XML_RPC!
4.1 Applying XML_RPC in PHP
PHP is an ideal language for providing Web services. We only need to write the PHP code and put it in a suitable location, and there will immediately be a service that can be "called" through the URL. XML_RPC implementation in PHP can be complex or simple, but we have many options. Here we choose the XML_RPC implementation from Useful Information Company. Its code and documentation can be downloaded from http://xmlrpc.usefulinc.com/.
The basic class of this XML_RPC implementation involves two files:
xmlrpc.inc: contains the classes required by the php client of XML_RPC
xmlrpcs.inc: contains the XML_RPC Classes required by php server
4.2 Client
Writing XML_RPC client means:
1. Create an XML_RPC request message
2. Setup XML_RPC parameters
3. Create an XML_RPC message
4. Send message
5. Get response
6. Interpret response
Please look at the following example:
<?php
$f=new xmlrpcmsg('examples.getStateName',array(new xmlrpcval(14, "int")));
$c= new xmlrpc_client("/RPC2", "betty.userland.com", 80);
$r=$c->send($f);
$v=$r->value() ;
if (!$r->faultCode()) {
print "status code". $HTTP_POST_VARS["stateno"] . "yes" .
$v->scalarval() . "<BR>";
print "<HR>This is the server's response<BR><PRE>" .
htmlentities($r->serialize()). "</PRE><HR> n";
} else {
print "Error: ";
print "Code: " . $r->faultCode() .
" Reason: '" .$r-> faultString()."'<BR>";
}
?>
In this example, we first create an XML_RPC message that calls the "examples.getStateName" method, and passed an integer parameter of type "int" with a value of 14. We then create a client that describes the URL to be called (path, domain, and port). Next, we sent the message, received the response object, and checked for errors. If there are no errors, we display the result.
The main functions used when writing RPC client programs are as follows:
To create a client:
$client=new xmlrpc_client($server_path, $server_hostname, $server_port) ;
The method to send a message is:
$response=$client->send($xmlrpc_message);
It returns an instance of xmlrpcresp. The message we pass is an instance of xmlrpcmsg, which is created with the following method:
$msg=new xmlrpcmsg($methodName, $parameterArray);
methodName is the method (process) to be called The name, parameterArray is a php array of xmlrpcval objects. For example:
$msg=new xmlrpcmsg("examples.getStateName", array(new xmlrpcval(23, "int")));
xmlrpcval object can be created in the following form:
<?php
$myVal=new xmlrpcval($stringVal);
$myVal=new xmlrpcval($scalarVal, "int" | "boolean" | "string" | "double" | "dateTime .iso8601" | "base64");
$myVal=new xmlrpcval($arrayVal, "array" | "struct");
?>
Created in the first form Is the xmlrpc string value. The second form creates a value that describes the value and type. The third form creates complex objects by combining other xmlrpc values in an array-like structure, for example:
<?php
$myArray=new xmlrpcval(array(new xmlrpcval("Tom") , new xmlrpcval("Dick"),new xmlrpcval("Harry")), "array");
$myStruct=new xmlrpcval(array(
"name" => new xmlrpcval("Tom") ,
"age" => new xmlrpcval(34, "int"),
"geek" => new xmlrpcval(1, "boolean")),"struct");
?>
The response object is of xmlrpcresp type and is obtained by calling the send method of the customer object.On the server side, we can create an object of type xmlrpcresp as follows:
$resp=new xmlrpcresp($xmlrpcval);
On the client side, use the following method to obtain xmlrpcval from the response :
$xmlrpcVal=$resp->value();
Next we can use the following method to obtain the PHP variable describing the response result:
$ scalarVal=$val->scalarval();
For complex data types, there are two functions that are very useful, both of which are in xmlrpc.inc:
$arr= xmlrpc_decode($xmlrpc_val);
This function returns a PHP array, which contains the data in the xmlrpcval variable $xmlrpc_val, which has been converted into the variable type of PHP itself.
$xmlrpc_val=xmlrpc_encode($phpval);
This function returns an xmlrpcval type value, which contains the PHP data described by $phpval. For arrays and structures, this method enables recursive analysis. Note that there is no support for non-basic data types (such as base-64 data, or date-time data).
4.3 Server side
It is very simple to use the class writing service provided by xmlrpcs.inc. To create a service, we create an instance of xmlrpc_server as follows:
<?php
$s=new xmlrpc_server( array("examples.myFunc" =>
array("function" => "foo")));
?>
What is passed to the xmlrpc_server constructor is an associative array of associative arrays. The procedure "examples.myFunc" calls the "foo" function, and for this reason foo is called a method handle.
Writing method handles is easy. Here is the skeleton of a method handle:
<?php
function foo ($params) {
global $xmlrpcerruser; // Introduce user error code value
// $params is a Array of xmlrpcval objects
if ($err) {
// Error condition
return new xmlrpcresp(0, $xmlrpcerruser+1, // User error 1
"Error!");
} else {
// Success
return new xmlrpcresp(new xmlrpcval("Fine!", "string"));
}
}
?>
As you can see, the program checks for errors and returns an error (starting from $xmlrpcerruser+1) if there is an error; otherwise, if everything is normal, it returns xmlrpcresp describing the success of the operation.
5. Application Example
In the following example we will construct a service. For a given value n, the service returns n*2. The client uses this service to calculate the value of 5*2.
The server-side code is as follows:
<?php
include("xmlrpc.inc");
include("xmlrpcs.inc");
function foo ( $params)
{
global $xmlrpcerruser; // Introduce user error code value
// $params is an array of xmlrpcval objects
$vala=$params->params[0];
$sval=$vala->scalarval();
$ret=$sval*2;
return new xmlrpcresp(new xmlrpcval($ret, "int"));
}
$s=new xmlrpc_server( array("product" =>
array("function" => "foo")));
?>
Client The code is as follows:
<?php
include("xmlrpc.inc");
if ($HTTP_POST_VARS["number"]!="") {
$f=new xmlrpcmsg ('product',array(new xmlrpcval($HTTP_POST_VARS["number"], "int")));
$c=new xmlrpc_client("/xmlrpc/servfoo.php", "luigi.melpomenia.com. ar", 80);
$c->setDebug(0);
$r=$c->send($f);
$v=$r->value() ;
if (!$r->faultCode()) {
print "Number ". $HTTP_POST_VARS["number"] . " is " .
$v->scalarval() . " <BR>";
print "<HR>Results from server!<BR><PRE>" .
htmlentities($r->serialize()). "</PRE><HR>n ";
} else {
print "Operation failed: ";
print "Code: " . $r->faultCode() .
" Reason: '" .$r-> faultString()."'<BR>";
}
}
print "<FORM METHOD="POST">
<INPUT NAME="number" VALUE="${number}" >
<input type="submit" value="go" name="submit"></FORM><P>
Enter a value";
?>
Conclusion: The operation of XML_RPC services also involves many other infrastructure and basic work, such as the cataloging and indexing mechanism of distributed processes, and better interfaces for processing XML_RPC in programming languages. There are a lot of reports about XML_RPC and the Serviced Web, so let's pay close attention to their development!