#native_company# #native_desc#
#native_cta#

Using XML: A PHP Developer’s Primer, Part 4, Section 2

By Adam Delves
on August 22, 2008

This is the second half of an article that began last week. If you haven’t read the first part, please do so before reading on…

Creating the PHP Server

The PHP RPC server uses the XML_RPC_Server object provided by the PEAR XML-RPC package. Both this and the EmailValidator object will be required in the server:

    require_once 'email_validator.php';
    require_once 
'XML/RPC/Server.php';

PHP functions cannot be mapped directly to the RPC server. The function you wish to map must be contained in a special RPC callable function. This function takes a single parameter which will be passed an XML_RPC_Message object when it is called. The function must return an XML_RPC_Response object containing the return value:

function strlen_rpc($message)
{
    
$string $message->params[0]->getVal(); // get the first parameter passed

    return new XML_RPC_Response(new XML_RPC_Value(strlen($string), 'int'));
}

The params property of the XML_RPC_Message object is an array of XML_RPC_Value objects containing the parameters passed to the function in the RPC call.

The next step is to map the function to a dispatch array so that it is ready to pass to the XML_RPC_Server object:

$functions = array('strlen' => array('function' => 'strlen_rpc'// this is the name of the php function to map
                                     
'signature' => array(array('int''string')),
                                     
'docstring' => 'Returns the length of a string.'));

       
The index name of each element (strlen in this case) is the name that the RPC client will use to call the function. The element itself is an array containing three items:

  • function: the name of the php function to map
  • signature: an array of arrays that describe the return data type and data type of the parameters expected. The first element is always the return type, the others are the data types of the parameters. Although this is optional, it should always be used, as the RPC server will check for the correct number of parameters and data type before invoking the callback and return a fault if they are incorrect.
  • docstring: An optional function documentation string that describes what the function does.

The final step is to create an instance of the XML_RPC_Server object and pass it to the array of dispatch function. The object immediately parses the contents of the HTTP request body and executes the appropriate function. The server always returns a valid XML-RPC response. Errors such as an invalid request will result in a fault response.

@(new XML_RPC_Server($functions1));

Two functions; emailValidator_validate (which validates the email address and sends the verification email) and emailValidator_verify (which verifies the verification code) will be mapped to the RPC server.

PHP – email_validate.php:

require_once 'email_validator.php';
require_once 
'XML/RPC/Server.php';

/* we first create an array which will map each function neededto the RPC server */
$functions = array('emailValidator.validate' => array('function' => 'emailValidator_validate',
                              
'signature' => array(array('struct','string'),
                                           array(
'struct''string''int')),
                                  
'docstring' =>'Validates the syntax of an email address.'),
                              
               
'emailValidator.verify' => array('function' => 'emailValidator_verify',
                            
'signature' => array(array('boolean','int','string')),
                                
'docstring' => 'Verifies an email verification code.
                                    Fault codes: -100 Error Creating / Getting email
                                             -101 Email not validated.
                                             -102 Invalid Email ID'
));
    
/* initialize the RPC server with the function map - parsing the request immdiatly */
@(new XML_RPC_Server($functions1));
    
/* this function is eecuted by the RPC, when a call is made to emailValidator.validate */
function emailValidator_validate($message)
{
    
/* get the email address */
    
$email_address $message->params[0]->getVal();
    
$email null;
    
$ret = array();

    if (isset($message->params[1])) {
        
/* if present, the second argument contains an integer ID */
        
$id $message->params[1]->getVal();
        
        try {
            
/* attempt to create an EmailValidator object using the ID */
           
$email = new EmailValidator($id);
           
$email->setEmail($email_address);
        
        } catch (
EmailValidatorException $e) {
           
// invalid ID; use the email address instead - ignore exception
        
}
    }

    if (! $email) {
        
/* create the EmailValidator using the email address supplied */
        
try {
           
$email = new EmailValidator($email_address);
        } catch(
Exception $e) {
           
/* we generate a fault here - as there is an error creating the EmailValidator object */
           
return new XML_RPC_Response(new XML_RPC_Value(''), '-100''Error creating or sending email.');
        }
    }

    /* we return two pices of information - the status of the validation and the new email ID (if any) */
    
$ret['validated'] = new XML_RPC_Value(validate_email($email), 'boolean');
    
$ret['email_id'] = new XML_RPC_Value($email->getId(), 'int');
    
    
/* return the reponse */
    
return (new XML_RPC_Response(new XML_RPC_Value($ret'struct')));
}

function emailValidator_verify($message)
{    
    
$id $message->params[0]->getVal();
    
$v_code $message->params[1]->getVal();

    try {
        $email = new EmailValidator($id);

        try {
            $ret $email->verify($v_code);
    
            return new 
XML_RPC_Response(new XML_RPC_Value($ret'boolean'));
        } catch (
EmailValidatorException $e) {
            return new 
XML_RPC_Response(new XML_RPC_Value(''), '-101''Email not validated.');
        }
    } catch (
EmailValidatorException $e) {
        return new 
XML_RPC_Response(new XML_RPC_Value(''), '-102''Invalid Email ID');
    }    
}