Skip to content
This repository was archived by the owner on Jan 16, 2019. It is now read-only.

Docs JsonRpc

Frank Kleine edited this page Apr 7, 2012 · 1 revision

Table of Contents

Easy AJAX with JSON-RPC

Stubbles helps you creating AJAX applications using the JSON-RPC protocol. To build an AJAX application with Stubbles, you do not need to know any details about JSON, the JSON-RPC protocol or the XmlHttpRequest implementations in different browsers. All you need is the YAHOO! User Interface Library, knowledge about PHP and some basic JavaScript knowledge.

Stubbles is able to expose any PHP class as a JSON-RPC service and will automatically generate JavaScript proxy classes for your PHP classes. This can either be done on the fly or during the build process of your application using a Phing task provided by Stubbles.

Prerequisites

The AJAX features of Stubbles make use of the ConnectionManager of the YAHOO! User Interface Library. So build an AJAX based application, you need to download the latest version of YUI. We recommend, that you at least install version 2.2.0 or higher. Since this version, it is also possible to use files provided by the YAHOO servers instead of a local copy.

If you need a performance boost and want to generate the proxy clients during the build process, you will need to install Phing, which is generally recommended when using Stubbles, but a mandatory requirement, when generating static JavaScript proxy classes.

Building the service classes

In the following example, you will learn, how to build a very small service that provides mathematical functions. At first, you start by implementing the PHP class and methods that you want to access via AJAX. There is no requirement at all for these classes, you may put them in any package and they do not need to extend any class or implement any interface.

A simple service to add two numbers would look like the following class:

<?php
/**
*Simple Math Service used for testing
 *
*@author      Stephan Schmidt <schst@stubbles.net>
*@package     stubbles_examples
*@subpackage  json_rpc
*/
class MathService {

    /**
***Add two numbers
     *
***@param int $arrKey
***@return string
***/
    public function add($a, $b) {
        return $a+$b;
    }
}
?>

This class can easily be used with the following PHP snippet:

<?php
$service = new MathService();
print $service->add(8, 12);
?>

To make the add() method callable via AJAX, you have to do a slight modification of the source code by adding the @WebMethod annotation to the method that should be exposed:

<?php
/**
*...
*/
class MathService {

    /**
***Add two numbers
     *
***@WebMethod
***@param int $arrKey
***@return string
***/
    public function add($a, $b) {
        return $a+$b;
    }
}
?>

This is needed for security reasons, so no one will be able to call methods that you do not want to expose as a service.

Adding the JSON-RPC processor

JSON-RPC services are made available via a processor, that can be hooked into the front-controller. So you need to register the :stubbles::service::jsonrpc::stubJsonRpcProcessor processor with the net&#58;&#58;stubbles&#58;&#58;websites&#58;&#58;ioc&#58;&#58;stubWebsiteBindingModule:

&lt;?php
stubWebsiteBindingModule&#58;&#58;createWithXmlProcessorAsDefault(&#39;interceptors&#39;)
                        &#45;&gt;enableJsonRpc(&#39;interceptors&#39;)
?&gt;

Now, the JSON-RPC processor will be available at http&#58;//www.example.com/path/to/stubbles/?processor&#61;jsonrpc

Registering the service

To expose the MathService class as a JSON-RPC service, you will have to adjust another configuration file in the config folder. The json&#45;rpc&#45;service.ini file contains mappings that define which PHP classes should be exposed as a service and how the JavaScript proxy classes should be named. Your configuration file should look similar to this:

&#91;classmap&#93;
MathService &#61; &quot;org&#58;&#58;stubbles&#58;&#58;examples&#58;&#58;service&#58;&#58;MathService&quot;
NameService &#61; &quot;org&#58;&#58;stubbles&#58;&#58;examples&#58;&#58;service&#58;&#58;RememberNameService&quot;

In this file, you may add as many service classes as you want to expose.

Accessing the service

Now you have finished all required steps for the server part of your AJAX application and can start consuming the service via JavaScript. For this you need to create an HTML page (for example using the XML/XSL processor of Stubbles) and include the following JavaScript files:

  • http&#58;//yui.yahooapis.com/2.7.0/build/utilities/utilities.js (YAHOO! User Interface Library)
  • javascript/json2.js (provided by json.org, but already bundled in Stubbles)
  • javascript/stub&#45;base.js (provided by Stubbles)
  • javascript/stub&#45;json&#45;rpc.js (provided by Stubbles)
  • /path/to/stubbles/?processor&#61;jsonrpc&amp;&#95;&#95;generateProxy&#61;MathService (generates JavaScript proxies on the fly)

So the HEAD part of your HTML document probably looks similar to this:

  &lt;script type&#61;&quot;text/javascript&quot; src&#61;&quot;javascript/stub&#45;json&#45;rpc.js&quot;&gt;&lt;/script&gt;
  &lt;script type&#61;&quot;text/javascript&quot; src&#61;&quot;/path/to/stubbles/?processor&#61;jsonrpc&amp;&lt;u&gt;generateProxy&#61;&lt;/u&gt;all&quot;&gt;&lt;/script&gt;
  ...
&lt;/head&gt;

In this case we are using the YUI files provided by YAHOO! hosting instead of installing the YAHOO! User Interface Library locally.

Passing &lt;u&gt;generateProxy&#61;MathService to the JSON-RPC processor will cause the processor to generate the JavaScript class for the MathService proxy. passing &lt;/u&gt;generateProxy&#61;&#95;&#95;all will tell the processor to generate proxy classes for all regsitered services. Additionally the service URL for the proxy classes has to be set as JavaScript Object:

&lt;script type&#61;&quot;text/javascript&quot;&gt;
stubbles.json.rpc.serviceUrl &#61; &#39;/path/to/stubbles/?processor&#61;jsonrpc&#39;&#59;
&lt;/script&gt;

Creating a callback object

All calls to Stubbles services are asynchronous. That means, that the client will not wait for the response, but you have to specify a callback object, that will be informed, when your service returns a response. The callback object for the MathService class should look similar to this:

var MathCallbackObj &#61; &#123;
  callback&#95;&#95;add&#58; function(id, result, error) &#123;
    alert(result)&#59;
  &#125;
&#125;&#59;

The object needs a callback method for every service method that is provided by the PHP service. Those methods need to be prefixed with callback&#95;&#95; and must accept three arguments:

  1. The id of the request
 2. The return value of the method
 3. An error that could have occurred

The return value will automatically be converted from PHP to JavaScript, that means, if you return a PHP string you will get a string in JavaScript and if you return an object in PHP, you will get an object in JavaScript.

Calling the service

The call a service, you have to instantiate the proxy class and pass the callback object, that you want to use:

var math &#61; new stubbles.json.proxy.MathService(MathCallbackObj)&#59;

The name of the class is the name you specified in the json&#45;rpc&#45;service.xml in the name attribute of a service binding, prefixed with the standard stubbles service namespace to avoid global namespace issues.

Now you may call the methods provided by your PHP class as if they were JavaScript methods:

math.add(12,8)&#59;

The method call will be encoded in JSON-RPC and send to the PHP service. The return value of the PHP method call will then be encoded in JSON-RPC and sent back to the client, which will result in a callback. This will happen transparently for your application.

Stateful services

In the example above, the service does not maintain any state between the different calls. In this case, that is not required for the service to work. But in some other cases, you might want to maintain state between the service calls and event between the standard HTTP requests that deliver HTML pages and the service calls.

To receive the session object for maintaining state, you can use the inversion of control features provided by Stubbles. All you need to do is implement a method that will accept an instance of stubSession and annotate it with the @Inject annotation:

    /&#42;&#42;
&#42;&#42;&#42;Set the session
     &#42;
&#42;&#42;&#42;@Inject
&#42;&#42;&#42;@param stubSession $session
&#42;&#42;&#42;/
    public function setSession(stubSession $session)
    &#123;
        $this&#45;&gt;session &#61; $session
    &#125;
&#125;
?&gt;

Your web-methods may now access the session to store and retrieve any data they need. For more information see the session documentation.

If you want your application to work with cookies disabled, you will have to tell the JSON-RPC proxies which session id they have to send to the server. This can be easily done by setting the stubbles.json.rpc.appendToUrl variable in JavaScript. How you retrieve the session id and write it to the variable depends on the view engine, you are using. Here is a simple example:

&lt;script type&#61;&quot;text/javascript&quot;&gt;
stubbles.json.rpc.appendToUrl &#61; &#39;&lt;?php echo $session&#45;&gt;getName()&#59;?&gt;&#61;&lt;?php $session&#45;&gt;getId()&#59;?&gt;&#39;&#59;
&lt;/script&gt;

Firebug support

Depending on the mode Firebug could be used for debugging purposes. When the mode is not stubMode&#58;&#58;$PROD, error messages will be sent to the Firebug console. See runtime modes for more informations on Stubbles' unified mode handling.

Further information

Further points of interest might be:

Clone this wiki locally