Implementing XML-RPC in PHP


The XML-RPC client and server classes exist for various languages including PHP. The xmlrpc.inc file provides XML-RPC client functions, and the xmlrpcs.inc file provides XML-RPC server functions. To check if the XML-RPC server successfully executes a client request, include the .inc files in the same directory as the PHP code.

Creating a Client Application

The XML-RPC client transfers a request to execute a particular method on the server. The request message consists of the arguments that the remote method accepts.

To create an XML-RPC client request using the XML-RPC class, the client needs to generate a client object. The client transfers and receives data from the XML-RPC server using the client object. The xmlrpc_client class creates a client object. The information that the client object constructor receives from the server includes:

  • The path to the script handling that the XML-RPC client requests .

  • The hostname or the IP address of the server.

  • The port number of the server.

The syntax of the xmlrpc_client class constructor is:

 $client=new xmlrpc_client($serverpath, $hostname, $port); 
Note  

The port parameter in the xmlrpc_client class constructor is optional. If you exclude the port parameter, its default value is set to 80 when you use HTTP as the transport layer.

The xmlrpc_client class constructor supports the following methods :

  • send() method : Sends the XML-RPC client message to the server. The syntax of the send() method is:

     $response=$client->send ($xmlrpc_message, $timeout, $server_method); 

    In the above syntax, $xmlrpc_message is an instance of the xmlrpcmsg class. The $timeout and $server_method parameters are optional. The $timeout parameter is set to 0, and the $server_method parameter to HTTP, if these are not specified in the syntax.

  • setDebug() method : Enables the client to display the debugging information on the browser. When debugging mode is on, the client object displays the response received from the server. The debugging information helps you locate low-level errors, such as no network connection to the server and the timeout expired errors. You can locate these errors because debugging information displays data that the server returns. The syntax of the setDebug() method is:

     $client->setDebug($debugmode); 
     $client->setDebug($debugmode); 

    In the above syntax, the value of the $debugmode parameter is either 0 or 1. The value, 0, of the $debugmode parameter indicates that the client does not display debugging information on the browser. If the $debugmode parameter is set to 1, the client displays the debugging information on the browser.

  • setCredentials() method : Enables you to set a user name and password for authorizing the client to access a server. The syntax of the setCredentials() method is:

     $client->setCredentials($user name, $password); 
Note  

The xmlrpc_client class constructor supports the setCertificate() method, which allows you to define a certificate necessary for establishing a connection over the Hyper Text Transfer Protocol Secure Sockets (HTTPS) protocol.

To create a client request, you can invoke the methods defined in the sample file, server.php, which is downloaded with the xmlrpc library. For example, you can create a client request that calls the interopEchoTests.echoValue method in the server.php file. The interopEchoTests.echoValue method echoes the value passed to it. The interopEchoTests.echoValue method does not accept any parameters.

Listing 6-4 shows an XML-RPC client request created using the PHP language:

Listing 6-4: XML-RPC Client Request in PHP
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); $msg=new xmlrpcmsg("interopEchoTests.echoValue"); $client=new xmlrpc_client("/server.php", "localhost", 80); $client->setDebug(1); //Debug mode is turned on. $response=$client->send($msg); //Invokes the remote method. ?> 
end example
 

The above listing shows how the client request calls the interopEchoTests.echoValue() method on the server.php server file. The client message does not pass any arguments to the called method. As a result, the server response consists of the client message itself.

Instead of calling methods predefined in the server.php file, you can create a server and define methods within it. For example, create a server, myserver.php, which contains the examples.multiply() method to multiply two integer values.

Listing 6-5 shows an XML-RPC client request in PHP to call the examples.multiply() method:

Listing 6-5: XML-RPC Client Request that Invokes the examples.multiply() Method
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); $msg=new xmlrpcmsg("examples.multiply", array(new xmlrpcval(13, "int"),  new xmlrpcval(2, "int"))); $client=new xmlrpc_client("/myserver.php", "localhost", 80); $client->setDebug(1); $response=$client->send($msg); ?> 
end example
 

The above listing shows the client request to invoke the examples.multiply() method available in the myserver.php file. The client request passes two integer parameters, 3 and 2, to this method.

Similarly, you can create a client request to add three floating-point values.

Listing 6-6 shows the client request to add three floating-point numbers :

Listing 6-6: The Client Request to Add Three Floating-point Numbers
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); $msg=new xmlrpcmsg("addDouble", array(new xmlrpcval(3.4, "double"),  new xmlrpcval(2.5, "double"), new xmlrpcval(1.2, "double"))); $client=new xmlrpc_client("/myserver.php", "localhost", 80); $client->setDebug(1); $response=$client->send($msg); ?> 
end example
 

The above listing shows the client request that passes three parameters of double data type to the remote method on the myserver.php server.

Figure 6-5 shows the server response after servicing the request to add three floating-point values:

click to expand: this figure shows the output obtained after the addition of three floating-point values. the output returned by the server is of the double data type.
Figure 6-5: The Server Response of the Client Application to Add Double Values

Creating a Request using XML-RPC

After you create the client object, you should pass a message object to it. The XML-RPC client transfers the message object to the server. The message consists of the name of the remote method that a client needs to invoke, and the parameters that this method accepts. To create a client request, you need to create an instance of the xmlrpcmsg class. The xmlrpcmsg class provides the method name along with its parameters that an XML-RPC client needs to invoke on a server. The syntax of the xmlrpcmsg class is:

 $msg=new xmlrpcmsg($method_name, $parameter_array); 

In the above syntax, the $method_name parameter is the string that denotes the name of the method to be invoked on the server. The $parameter_array parameter is an array of objects that the xmlrpcval class creates.

An alternative method to represent the xmlrpcmsg class constructor is:

 $msg=new xmlrpcmsg($method_name); 

In the above syntax, the client does not pass any parameters to the remote method.

The xmlrpcval class encloses values of the specified data types to obtain the XML-RPC server response. It stores complex values using the XML-RPC data types. The following multiple forms show the use of the xmlrpcval class:

 $val=new xmlrpcval(); $val=new xmlrpcval($stringvalue); $val=new xmlrpcval($scalarvalue, "int""boolean""string""double""dateTime.iso8601""base64"); $val=new xmlrpcval($arrayvalue, "array""struct"); 

In the above forms, the first xmlrpc class constructor creates an empty value. The second constructor creates a string value. The third constructor consists of two parameters. The first parameter of the third constructor indicates that the xmlrpcval class creates a scalar value. The second parameter denotes the XML-RPC data type. The fourth constructor contains the $arrayvalue parameter, which is either a simple array or an associative array, depending upon the data type.

You should provide parameters within an array, even if the client has only one parameter to pass to the remote method. It is not necessary to provide parameters for the remote method during the initialization of the xmlrpcmsg class instance. You can use the addParam() method to add the method parameters after the XML-RPC client creates the xmlrpcmsg class instance. The syntax of the addParam() method is:

 $msg->addParam($xmlrpcval); 

For example, the code snippet showing the client request using the XML-RPC library classes, xmlrpcmsg and xmlrpcval, is:

 $msg=new xmlrpcmsg("calculate.area", array(new xmlrpcval(14, "int"), new xmlrpcval(23, "int"))); 

The above code shows the client request that invokes the calculate.area() method to calculate the area of a rectangle. The client passes two integer parameters, 23 and 14, which denote the length and breadth of the rectangle.

You can also provide a parameter array to the remote method. For example, the following code shows the client request that transfers an array of parameters to the remote method, examples.salary:

 $input=array("Kim"=>2300, "Erwin"=>5000, "Crisp"=>9000); while(list($key, $val)=each($input)) {    $outp[ ]=new xmlrpcval(array("name"=>new xmlrpcval($key),"sal"=>new xmlrpcval($val,    "int")), "struct"); } $f=new xmlrpcmsg("examples.salary",array(new xmlrpcval($outp, "array"))); 

The above code shows the client request that invokes the examples.salary() method to sort the employee names on the basis of the salary. The input parameters passed to the remote method are the name and salary of the employee.

Sending a Request to the Server

After the client creates the client object and request message, it transfers the request message to the server. To transfer the client request to a remote server, the client creates a request message and passes it to the send() method. There are two ways to invoke the send() method:

 $xmlrpc_resp=$client->send($msg); $xmlrpc_resp=$client->send($msg, $timeout); 

In the above syntax, the second form describes a timeout parameter after which the message is timed out. You should represent the timeout parameter in seconds. The $msg parameter specifies the method name and its parameters.

If the client request executes successfully, the send() method returns an instance of the xmlrpcresp class. If a low-level error occurs, the send() method returns 0. The low-level error occurs either if the client cannot connect to the server, or if the client cannot transfer the request to the server. The xmlrpcresp class contains the responses to the XML-RPC requests.

Note  

Turn on the client object debugging mode to check the cause of the low-level error.

An XML-RPC server is a PHP script similar to an XML-RPC client. The XML-RPC server contains methods that a client can access remotely. It is not necessary that the name of the method, which a client uses, should be the same as the method name on the server. PHP maps the Web service API procedure names, and the name of the PHP functions that implement those procedures on the server. For example, the examples.multiply() method that the client invokes is mapped to the multiply() method on the server. The following code shows the multiply() method on the XML-RPC server:

 function multiply($m)  {    $s=$m->getParam(0);    $t=$m->getParam(1);    return new xmlrpcresp(new xmlrpcval($s->scalarval()*$t->scalarval(), "int")); } 

In the above code:

  • The multiply() method accepts the xmlrpcmsg class instance as a single argument.

  • The getParam() method accesses the parameters of the multiply() method as instances of the xmlrpcval class in the request message.

  • An instance of the xmlrpcresp class returns the value of the multiply() method to the calling function.

You can create an instance of the xmlrpcresp class using one of the following syntaxes:

  • new xmlrpcresp (0, $errno, $errmsg) : Contains three arguments. The first argument, 0, indicates that the value that a server returns is a fault condition. The second argument, $errno, indicates the fault number and the third parameter, $errmsg, indicates the error description.

  • new xmlrpcresp ($xmlrpcVal) : Returns the value of the method if the client request is successfully executed.

To obtain the response to an XML-RPC client request, the server should execute the invoked method. A dispatch map stores the description of all methods defined in the XML-RPC server. A dispatch map is an associative array that maps the Web service API procedure names with the names of the PHP methods that implement those procedures on the server. The following code shows the dispatch map for the client request that calls the examples.multiply() method on the server:

 //Represents the signature of the multiply() method. $multiply_sig=array(array($xmlrpcInt, $xmlrpcInt, $xmlrpcInt)); //Represents the documentation for the multiply() method. $multiply_doc='Multiplies two integers together and return an result type';  //Represents dispatch map. $dm=array("examples.multiply"=>array("function"=>"multiply", "signature"=>$multiply_sig, "docstring"=>multiply_doc)); 

The above code shows the dispatch map for the multiply() method. The dispatch map points to the signature of the multiply() method, along with the documentation for the multiply() method. PHP maps the examples.multiply() method to the PHP function that implements the called procedure on the server.

Each instance of the array in the dispatch map needs the following parameters:

  • function : Represents the exact name of the PHP function on the server that defines the functioning of the method that the XML-RPC client calls. It is a string value.

  • signature : Represents the data type of the parameters, along with the method return type, that you need to pass to the method. You can define multiple signatures so that a method can have different number and type of parameters. When the client invokes a particular method, the server verifies if the data type of the arguments passed by the client matches any of the signatures in the dispatch map. An error occurs if the data type of the arguments does not match.

  • docstring : Represents a string that contains the documentation for a method on the server. The method documentation explains the operation that a method performs .

You need to pass the dispatch map as an instance of the xmlrpc_server class. To get the client request serviced by a server:

  1. Include the xmlrpcs.inc file, in addition to the xmlrpc.inc file, in the server PHP script.

  2. Create the xmlrpc_server class instance that accepts the dispatch map as its argument.

The xmlrpc_server class instance services the client request.

Listing 6-7 shows the PHP server script that services the client request to multiply two integer values:

Listing 6-7: PHP Server Script to Multiply Two Integers
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); include("/xmlrpc-1.0.99.2/xmlrpcs.inc"); $multiply_sig=array(array($xmlrpcInt, $xmlrpcInt, $xmlrpcInt)); $multiply_doc='Multiplies two integers together and return the result'; function multiply($m) { $s=$m->getParam(0); $t=$m->getParam(1); return new xmlrpcresp(new xmlrpcval($s->scalarval()*$t->scalarval(), "int")); } $res=new xmlrpc_server(array("examples.multiply"=>array("function"=>"multiply", "signature"=>$multiply_sig, "docstring"=>multiply_doc), "interopEchoTests.echoValue" =>array("function" => "i_echoValue", "docstring" => $i_echoValue_doc))); ?> 
end example
 

The above listing shows the server script that services the client request to multiply two integer values.

Similarly, you can create the server that arranges employee names based on their salaries.

Listing 6-8 shows the PHP server script that services the client request to arrange employee names based on their salaries:

Listing 6-8: PHP Server Script to Sort Employees
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); include("/xmlrpc-1.0.99.2/xmlrpcs.inc"); function salary_compare($a, $b)  {    global $salary_arr;    $a=ereg_replace("-", "", $a);    $b=ereg_replace("-", "", $b);    if ($salary_arr[$a]==$salary[$b]) return 0;    return ($salary_arr[$a] > $salary_arr[$b]) ? 1 :1; } $salary_sig=array(array($xmlrpcArray, $xmlrpcArray)); $salary_doc='Send this method an array of [string, int] structs'; function salary($m)  {    global $salary_arr, $xmlrpcerruser, $s;    xmlrpc_debugmsg("Entering 'salary'");    // get the parameter    $sno=$m->getParam(0);    // error string for [ifwhen] things go wrong    $err="";    // create the output value    $v=new xmlrpcval();    $agar=array();    if (isset($sno) && $sno->kindOf()=="array")     {       $max=$sno->arraysize();       // print "<!-- found $max array elements -->\n";       for($i=0; $i<$max; $i++)        {          $rec=$sno->arraymem($i);          if ($rec->kindOf()!="struct")           {             $err="Found non-struct in array at element $i";             break;          }          // extract name and salary from struct          $n=$rec->structmem("name");          $a=$rec->structmem("sal");          // $n and $a are xmlrpcvals,          // so get the scalarval from them          $agar[$n->scalarval()]=$a->scalarval();         }         $salary_arr=$agar;         uksort($salary_arr, salary_compare);         $outAr=array();         while (list($key, $val) = each($salary_arr))          {             // recreate each struct element             $outAr[]=new xmlrpcval(array("name" =>  new xmlrpcval($key), "salary" => @ new             xmlrpcval($val, "int")), "struct");          }          // add this array to the output value          $v->addArray($outAr);     }     else      {       $err="Must be one parameter, an array of structs";     }    if ($err)      {       return new xmlrpcresp(0, $xmlrpcerruser, $err);     }     else     {       return new xmlrpcresp($v);     } } $res=new xmlrpc_server(array("examples.salary"=>array("function"=>"salary", "signature"=>$salary_sig, "docstring"=>salary_doc))); ?> 
end example
 

The above listing shows that the PHP server script services the client request to sort employee names based on their salaries. The client calls the examples.salary function, and PHP maps the called function to the salary() method on the server. The salary() method calls the salary_compare() method to compare the salaries of the employees.

XML-RPC messages support various data types. You can create a client request that passes floating-point data as the method parameter.

Listing 6-9 shows the PHP server script that adds three double data type values:

Listing 6-9: PHP Server Script to Add Double Values
start example
 <?php include("/xmlrpc-1.0.99.2/xmlrpc.inc"); include("/xmlrpc-1.0.99.2/xmlrpcs.inc"); $add_sig=array(array($xmlrpcDouble, $xmlrpcDouble, $xmlrpcDouble, $xmlrpcDouble)); $add_doc='Add three double values and return a value with type double.'; function add($m)  {    $s=$m->getParam(0);    $t=$m->getParam(1);    $r=$m->getParam(2);    return new xmlrpcresp(new xmlrpcval($s->scalarval()+$t->scalarval()+$r->scalarval(),    "double")); } $resp=new xmlrpc_server(array("addDouble"=>array("function"=>"add", "signature"=>$add_sig, "docstring"=>$add_doc))); ?> 
end example
 

The above listing shows that PHP maps the addDouble() function to the add() function in the PHP script. The signature of the add function specifies that the function accepts three double values as input and returns a single double type value.

Processing the Server's Response

The XML-RPC server returns a response when it successfully completes a transaction with the client object. The response that the server returns denotes an instance of the xmlrpcresp class. If the XML-RPC server does not complete a successful transaction with the client object, it returns a fault condition. As a result, the instance of the xmlrpcresp class is either a normal response or a fault condition. The XML-RPC response is a fault condition either if the server does not understand the client request or if there is any low-level error.

The xmlrpcresp class provides the following two methods to check if the server response is a fault condition:

  • faultCode() method : Returns 0, if there is no fault condition. If a fault occurs, it returns the ID number that the server assigns to the fault.

  • faultString() method s: Returns the description of the fault that occurs.

If the server successfully executes the client request, the instance of the xmlrpcresp class returns the data from the called procedure. The value() method accesses data that an instance of the xmlrpcresp class returns. The syntax of the value() method is:

 $xmlrpcVal=$resp->value(); 

In the above syntax, $xmlrpcVal is an instance of the xmlrpcval class that contains the value that the server returns. The client process does not use the value that the value() method returns, if the faultCode is nonzero.

If the client request to multiply two integer values executes successfully, the server response returns the required result.

Figure 6-6 shows the server response to the client request for multiplying two integers, 13 and 2:

click to expand: this figure shows that the output of the multiply() method is an integer value, 26.
Figure 6-6: The Server Response of Multiplying Two Integers

If the client cannot successfully communicate with the server, a fault condition occurs in the server response.

Figure 6-7 shows the server response to an unsuccessful client request to multiply two integers:

click to expand: this figure shows the unsuccessful server response when the client passes only a single argument to the remote function instead of two arguments.
Figure 6-7: Unsuccessful Server Response of Multiplying Two Integers

Similarly, you can obtain the server response for the client request to sort employee names on salary basis.

Figure 6-8 shows the server response with employee names sorted on the basis of their salaries:

click to expand: this figure shows the employee names sorted on the basis of salaries. the response is obtained as an instance of the xmlrpxval class.
Figure 6-8: The Server Response to Sort Employees

When an XML-RPC client makes a request to the server, the server response can be in one of the following forms:

  • Low-level I/O error

  • Valid XML-RPC response

  • XML-RPC error condition

PHP has certain fault codes that XML-RPC classes use to indicate the type of fault. If an XML-RPC error condition occurs, the XML-RPC classes display the corresponding fault code and its description.

Table 6-1 describes the various fault codes:

Table 6-1: Fault Codes in PHP

Fault code

Fault description

Cause of error

1

Unknown method

Occurs when the client requests for a method that is not defined in the server.

2

Invalid return payload

Occurs when the client receives an invalid XML-RPC response from the server.

3

Incorrect parameters passed to method

Occurs when the client passes either incorrect number of parameters or incorrect data type of the parameter to the remote function.

4

Didn t receive 200 OK from the server

Occurs when there is an HTTP transport error.

XML-RPC provides interoperability between different platforms and languages. You can implement XML-RPC in PHP to write client and server scripts. You use the extensions of the XML-RPC protocol to authenticate the end users using the server scripts and provide an asynchronous transmission system.




Integrating PHP and XML 2004
Integrating PHP and XML 2004
ISBN: N/A
EAN: N/A
Year: 2004
Pages: 51

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net