PHP XML-RPC Server Helper

I wrote a XMLRPCServerHelper to help me to create XML-RPC service in PHP.
It's easy to use and you just need to set the classname of service and all the methods will be extracted automatically using ReflectionClass.

The example of the server :

<?php
error_reporting(E_ERROR | E_PARSE);
require_once("autoload.php");

$server = new XMLRPCServerHelper();
$server->setClassName("TestXMLRPCService");
$answer = $server->handle();
header('Content-Type: text/xml');
print($answer);
?>


The service can be access from your normal webserver url.
To generate php client class, just simply add ?phpwrapper to the url. E.g :

 http://localhost/xmlrpc/server.php?phpwrapper


XMLRPCServerHelper.php . This file also incuded in my training materials on my previous post.

<?php

/**
 * This helper class help to create XML-RPC server
 */
class XMLRPCServerHelper {

    /**
     * Server handler holder
     * @var <Object> Server handler holder
     */
    private $serverHandler;
    /**
     * Class name holder
     * @var <string> Class name holder
     */
    private $classname;
    /**
     * External function list holder
     * @var <array>  External function list holder
     */
    private $externalFunctions;

    /**
     * Contructor
     */
    public function __construct() {
        $this->serverHandler = xmlrpc_server_create();
        $this->externalFunctions = array();
    }

    /**
     * Set object class.
     * All class methods will be extracted and registerd automatically
     * @param <Object> $class
     */
    public function setClassName($classname) {
        $this->classname = $classname;
        $reflection = new ReflectionClass($classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    $methodparams[] = $reflectparams[$j]->name;
                }
            } else {
                $methodparams = array();
            }
            $this->registerMethod($methodname, array(&$classname, $methodname), $methodparams);
        }
    }

    /**
     * Generate client wrapper
     */
    private function generatePHPClientWrapper() {
        $classfunctions = "";
        $reflection = new ReflectionClass($this->classname);
        $methods = $reflection->getMethods();
        $props = $reflection->getProperties(ReflectionProperty::IS_PUBLIC | ReflectionProperty::IS_PROTECTED);
        for ($i = 0; $i < count($methods); $i++) {
            $reflectmethod = $methods[$i];
            $methodname = $reflectmethod->name;
            $reflectparams = $reflectmethod->getParameters();
            $funcParams = "";
            $funcContent = "";
            if (count($reflectparams) > 0) {
                for ($j = 0; $j < count($reflectparams); $j++) {
                    //$funcContent.= "\$params[] = \$" . $reflectparams[$j]->name . ";\n";
                    if ($funcParams != "") {
                        $funcParams.=",";
                    }
                    $funcParams.='$' . $reflectparams[$j]->name;
                }
                $funcContent = "\$params = array($funcParams);\n";
            } else {
                $funcContent = "\$params = array();\n";
            }

            $classfunctions.="public function $methodname($funcParams) {\n";
            $classfunctions.=$funcContent;
            $classfunctions.="return \$this->sendRequest(\"$methodname\", \$params);\n";
            $classfunctions.="}\n\n";
        }

        $wrapper = "<pre>class " . $this->classname . "XMLRPCClient extends XMLRPCClientHelper {\n";
        $wrapper .= "$classfunctions";
        $wrapper .= "}\n</pre>";
        return $wrapper;
    }

    /**
     * Register method
     * @param <string> $externalName class name
     * @param <Object> $function class pointer
     * @param <array> $parameterNames parameters name
     */
    public function registerMethod($externalName, $function, $parameterNames) {
        if ($function == null) {
            $function = $externalName;
        }
        xmlrpc_server_register_method($this->serverHandler, $externalName, array(&$this, 'callMethod'));
        $this->externalFunctions[$externalName] = array('function' => $function, 'parameterNames' => $parameterNames);
    }

    /**
     * Invoke class method
     * @param <string> $functionName method name
     * @param <array> $parametersFromRequest parameters
     * @return <variant> function call result
     */
    public function callMethod($functionName, $parametersFromRequest) {
        if ($functionName == "generatePHPClientWrapper") {
            return $this->generatePHPClientWrapper();
        }

        $function = $this->externalFunctions[$functionName]['function'];
        $parameterNames = $this->externalFunctions[$functionName]['parameterNames'];
        return call_user_func_array($function, $parametersFromRequest);
    }

    /**
     * Handle server call
     * @return <variant>  function call result
     */
    public function handle() {
        $bWrapper = false;
        foreach ($_GET as $key => $value) {
            if ($key == "phpwrapper") {
                $bWrapper = true;
                continue;
            }
        }

        if ($bWrapper) {
            print $this->generatePHPClientWrapper();
            exit();
        }
        return xmlrpc_server_call_method($this->serverHandler, file_get_contents('php://input'), null);
    }

}

?>

0 comments:

 
Copyright © peyotest