/** * Constructor will serve any JSON-RPC request received and terminate processing, or return * control to the page to continue. * @param Object $object The object whose methods will be made available for JSON RPC calls. * @param Array $methodMap An optional associative array that can be used to map RPC method * names to object methods, permitting renaming of methods. This is * useful for providing PHP reserved words as methods, such as 'echo', * and can be used for restricting access to methods. If this parameter * is provided, but a method is not listed in the array, access to the method * is denied. * @param Array $config Optional configuration array. Two associative values are supported: * 'jsonlib' The location of the JSON-PHP library file. * 'jsolaitlib' The directory off which jsolait has been installed. * * @return None If a valid JSON RPC Request has been received, JSONRpcServer will return a response and terminate * the page. If no such request has been received, JSON RPC will pass control back to the web page, and * a call to JSONRpcServer::javascript( proxyName ) will insert the appropriate JavaScript proxy code into your * web page source. * */ function JSONRpcServer($object, $methodMap = null, $config = null) { /* * NOTE: The request object ($request) is parsed into an object, but the response object * is an associative array. Writing this code, this distinction caused me headaches. Just a * warning :-) */ $this->jsonlib = JSON_PHP_FILE; $this->jsolaitlib = JSOLAIT_ROOT; if ($config != null) { if (array_key_exists("jsonlib", $config)) { $this->jsonlib = $config["jsonlib"]; } if (array_key_exists("jsolait", $config)) { $this->jsolaitlib = $config["jsolait"]; } } $json = new PHPJsonWrapper($this->jsonlib); $additionalMethods = array(); $input = file_get_contents("php://input"); $request = $json->decode($input); /* * If we have no request object, we are processing our page, so prepare the js Wrappers */ if ($request == null) { $this->object = $object; $this->methodMap = $methodMap; return; } $return = array("id" => $request->id, "result" => null, "error" => null); /* We've got the incoming JSON request object in request - we need to identify the method and the parameters */ $method = $request->method; /* The methodMap parameter can convert a named method as follows: * string => string - simply rename the method * string => anything else - permit access to the method (the actual boolean value does not matter) */ if ($methodMap != null) { if (array_key_exists($method, $methodMap)) { if (is_string($methodMap[$method])) { $method = $methodMap[$method]; } } else { $return['error'] = "No such method (" . $method . ") permitted on this server."; return $json->encode($return); } } if (is_object($object)) { if (!method_exists($object, $method)) { $return['error'] = "No such method (" . $method . ") exists on this server."; } else { /* * TODO: Try to catch an error in the call: use set_error_handler and restore_error_handler...? */ $return['result'] = call_user_func_array(array(&$object, $method), $request->params); } } else { decho("/* object = {$object} */"); if (!function_exists($method)) { $return['error'] = "No such function (" . $method . ") exists on this server."; } else { $return['result'] = call_user_func_array($method, $request->params); } } print $json->encode($return); exit(0); }
<?php /** * Internal code for the JSONRpcProxy::__call function * This _extremely_ annoying approach is necessitated to have PHP 4 and PHP 5 compatibility with the same code-base. * I SINCERELY hope it works! */ $json = new PHPJsonWrapper($this->jsonlib); $postData = array("id" => "remoteRequest", "method" => $method, "params" => $args); $postData = $json->encode($postData); /* Make a HTTP Post Request */ $jsonresult = $this->httpWrap->post($this->url, $postData); /* Some debugging code echo "<b>JSONRpcProxy::$method received:</b><br/><pre>"; echo str_replace(array("<",">"),array("<>"), $jsonresult); echo "</pre><hr>"; */ $result = $json->decode($jsonresult); if (is_object($result) && $result->id == "remoteRequest") { $return = array($result->result, $result->error); } else { $return = array(null, "JSON-RPC call failed.", $jsonresult); }