Skip to content


Subversion checkout URL

You can clone with
Download ZIP
An example web application using the wigwam php framework.
Fetching latest commit...
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
rpc @ 1097c26


Wigwam is a simple PHP web framework. This is an example application using it.


In a shell do the following commands:

    # Cd to your public html directory or docroot
    cd ~/public_html

    # Clone this repository and install the wigwam framework
    git clone
    cd wigwam-example
    git submodule init
    git submodule update

    # Create an appropriate htaccess file
    cp rpc/htaccess.example rpc/.htaccess
    vi rpc/.htaccess

Quick Start

Point your browser to your newly installed application. You can open the JavaScript console and watch the xhr traffic, and experiment with commands like these:

    // Run a remote command in synchronous mode
    with (Wigwam.sync) {

    // Run a remote command in asynchronous mode
      function(data) { console.log(data) },
      function(err) { alert(err) }

    // Exception handling
    with (Wigwam.sync) {
      var App = Wigwam.Test.App;

      console.log("1 + 1 = " + App.getOops(1, 1));

      // This will fail with a Wigwam.NotAllowed exception
      try {
        console.log("200 + 1 = " + App.getOops(200, 1));
      } catch (err) {
        if (err instanceof Wigwam.NotAllowed)
          alert("unexpected exception type: " + err);

What's Going On

There are four components in the application:

  1. The rpc/index.php file, which loads and configures the framework.
  2. The Wigwam\HTTP class, which takes care of the HTTP layer, doing all of the content negotiation, session management, etc.
  3. The API classes that are inserted into the Wigwam\HTTP instance. Their public static methods are automatically exported to the JavaScript environment.
  4. The index.html file, which loads the wigwam JavaScript runtime and makes RPC calls.

The server-side code that is being executed is the public static methods of the API class as configured in rpc/index.php:


    use Wigwam\HTTP;
    use Wigwam\Test\App;

    // CLASSLOADER INITIALIZATION                                                //

    require 'classes/Wigwam/ClassLoader.php';


    function main() {
      // Config files are processed in order. Settings in files processed later
      // will overwrite settings from files processed earlier.
      $config_files = array('config/config.yaml', 'config/config.local.yaml');

      // Create new HTTP wrapper instance.
      $http = new HTTP($config_files);

      // Load the application API into the HTTP wrapper.
      $http->addApi(new App());

      // Delegate to the HTTP wrapper.


The API class rpc/classes/Wigwam/Test/App.php used in this example is a minimal implementation:

    <?php namespace Wigwam\Test;

    use Wigwam\HTTP\Auth\Roles;

    class App {

       * This implements the App interface (unofficial). Used by the HTTP wrapper
       * for roles based auth. You'd normally subclass the Roles class to implement
       * your own roles based auth system.
       * @return object The roles subclass object.
      public function getRoles() {
        return new Roles();

       * Public static method: this method will be part of the public API, access-
       * ible via the HTTP interface. You'd call this method with a GET request to
       * /Wigwam/Test/App/getDoit. The response should be an object with the pro-
       * perty 'did' set to the value 'bar', in the format specified by the request
       * accepts header (i.e., Accepts: application/json -> { "did" : "it" }).
       * In PHP:
       *   \Wigwam\Test\App::getDoit();
       *   => array('did' => 'it')
       * In JavaScript:
       *   with (Wigwam.sync) {  // synchronous
       *     Wigwam.Test.App.getDoit();
       *   }
       *   => { "did" : "it" }
       *   Wigwam.async(  // asynchronous
       *     Wigwam.Test.App.getDoit(),
       *     function(data) { console.log(data) },
       *     function(err) { alert(err) }
       *   );
       * Here we use the wigwam base roles class, so any role (including deny) 
       * will pass. Normally you'd subclass it to have a functioning roles-based 
       * authorization and authentication system.
       * @role deny
       * @return array What it did.
      public static function getDoit() {
        return array('did' => 'it');

       * This method will throw an exception that can be caught in JS. Any
       * exception which is a subclass of Wigwam\Exception can be caught in
       * the client. If an exception of any other type is thrown and not
       * handled by the API class, it is converted to a generic exception of
       * type Wigwam\Exception and passed on to the client.
       * @param foo number The foo.
       * @param bar number The bar.
       * @return number The sum of the foo and the bar.
       * @throws \Wigwam\NotAllowed
      public static function getOops($foo, $bar) {
        if ($foo > 100)
          throw new \Wigwam\NotAllowed("too much foo", array('bar' => 'baz'));
        return $foo + $bar;

The index.html file contains the presentation layer of the application. It uses JavaScript to perform any UI (user interface) logic. Data is fetched from and returned to the server via the wigwam RPC (remote procedure call) framework.

        <script type="text/javascript" src="js/jquery.js"></script>
        <!-- Wigwam.js depends on jQuery -->
        <script type="text/javascript" src="rpc/wigwam.js"></script>
        <script type="text/javascript">
          with (Wigwam.sync) {
            $(function() {
              $("code").click(function() {
                // Do a synchronous RPC call to \Wigwam\Test\App::getDoit()
        <style type="text/css">
          body { font-family: sans-serif; }
          code { border: 1px solid darkgray; padding: 5px; margin: 2px;
                 cursor: pointer; }
        <p>What I did: <code>nothing yet (click me)</code></p>
Something went wrong with that request. Please try again.