27.5.Zend_Json_Server - JSON-RPC server
Zend_Json_Server is a JSON-RPC server implementation. It supports both the JSON-RPC version 1 specification as well as the version 2 specification; additionally, it provides a PHP implementation of the Service Mapping Description (SMD) specification for providing service metadata to service consumers.
JSON-RPC is a lightweight Remote Procedure Call protocol that utilizes JSON for its messaging envelopes. This JSON-RPC implementation follows PHP's SoapServer API. This means that in a typical situation, you will simply:
Instantiate the server object
Attach one or more functions and/or classes/objects to the server object
handle() the request
Zend_Json_Server utilizes 第46.2节 “Zend_Server_Reflection” to perform reflection on any attached classes or functions, and uses that information to build both the SMD and enforce method call signatures. As such, it is imperative that any attached functions and/or class methods have full PHP docblocks documenting, minimally:
All parameters and their expected variable types
The return value variable type
Zend_Json_Server listens for POST requests only at this time; fortunately, most JSON-RPC client implementations in the wild at the time of this writing will only POST requests as it is. This makes it simple to utilize the same server end point to both handle requests as well as to deliver the service SMD, as is shown in the next example.
例27.1.Zend_Json_Server Usage
First, let's define a class we wish to expose via the JSON-RPC server. We'll call the class 'Calculator', and define methods for 'add', 'subtract', 'multiply', and 'divide':
/** * Calculator - sample class to expose via JSON-RPC */ class Calculator { /** * Return sum of two variables * * @param int $x * @param int $y * @return int */ public function add($x, $y) { return $x + $y; } /** * Return difference of two variables * * @param int $x * @param int $y * @return int */ public function subtract($x, $y) { return $x - $y; } /** * Return product of two variables * * @param int $x * @param int $y * @return int */ public function multiply($x, $y) { return $x * $y; } /** * Return the division of two variables * * @param int $x * @param int $y * @return float */ public function divide($x, $y) { return $x / $y; } }Note that each method has a docblock with entries indicating each parameter and its type, as well as an entry for the return value. This is absolutely critical when utilizing Zend_Json_Server -- or any other server component in Zend Framework, for that matter.
Now we'll create a script to handle the requests:
$server = new Zend_Json_Server(); // Indicate what functionality is available: $server->setClass('Calculator'); // Handle the request: $server->handle();However, this will not address the issue of returning an SMD so that the JSON-RPC client can autodiscover methods. That can be accomplished by determining the HTTP request method, and then specifying some server metadata:
$server = new Zend_Json_Server(); $server->setClass('Calculator'); if ('GET' == $_SERVER['REQUEST_METHOD']) { // Indicate the URL endpoint, and the JSON-RPC version used: $server->setTarget('/json-rpc.php') ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2); // Grab the SMD $smd = $server->getServiceMap(); // Return the SMD to the client header('Content-Type: application/json'); echo $smd; return; } $server->handle();If utilizing the JSON-RPC server with Dojo toolkit, you will also need to set a special compatibility flag to ensure that the two interoperate properly:
$server = new Zend_Json_Server(); $server->setClass('Calculator'); if ('GET' == $_SERVER['REQUEST_METHOD']) { $server->setTarget('/json-rpc.php') ->setEnvelope(Zend_Json_Server_Smd::ENV_JSONRPC_2); $smd = $server->getServiceMap(); // Set Dojo compatibility: $smd->setDojoCompatible(true); header('Content-Type: application/json'); echo $smd; return; } $server->handle();
27.5.1.Advanced Details
While most functionality for Zend_Json_Server is spelled out in , more advanced functionality is available.
27.5.1.1.Zend_Json_Server
Zend_Json_Server is the core class in the JSON-RPC offering; it handles all requests and returns the response payload. It has the following methods:
addFunction($function): Specify a userland function to attach to the server.
setClass($class): Specify a class or object to attach to the server; all public methods of that item will be exposed as JSON-RPC methods.
fault($fault = null, $code = 404, $data = null): Create and return a Zend_Json_Server_Error object.
handle($request = false): Handle a JSON-RPC request; optionally, pass a Zend_Json_Server_Request object to utilize (creates one by default).
getFunctions(): Return a list of all attached methods.
setRequest(Zend_Json_Server_Request $request): Specify a request object for the server to utilize.
getRequest(): Retrieve the request object used by the server.
setResponse(Zend_Json_Server_Response $response): Set the response object for the server to utilize.
getResponse(): Retrieve the response object used by the server.
setAutoEmitResponse($flag): Indicate whether the server should automatically emit the response and all headers; by default, this is true.
autoEmitResponse(): Determine if auto-emission of the response is enabled.
getServiceMap(): Retrieve the service map description in the form of a Zend_Json_Server_Smd object
27.5.1.2.Zend_Json_Server_Request