PhpRiot
Become Zend Certified

Prepare for the ZCE exam using our quizzes (web or iPad/iPhone). More info...


When you're ready get 7.5% off your exam voucher using voucher CJQNOV23 at the Zend Store

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, 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 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.

Example 508. 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':

<?php
/**
 * 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:

<?php
$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:

<?php
$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:

<?php
$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();

Zend Framework