Out of Mind

Do less, and then do even less

November 9, 2010 at 9:43am

Home

Lithify It Like Sinatra

Lithium, the awesome php framework nearly released it’s 1.0 version. One of the awesomness of Lithium is it’s flexibility. It’s very flexible so you can use it as a Sinatra equivalent in PHP. Let’s take a look.

RESTful Routing

Lithium can do RESTful routing like this:

// GET request
Router::connect("/create", array("http:method" => "GET"),
    function($request){
        // Do something and return Response object
    }
);

// POST request
Router::connect("/create", array("http:method" => "POST"),
    function($request){
        // Do something and return Response object
    }
);

// PUT request
Router::connect("/create", array("http:method" => "PUT"),
    function($request){
        // Do something and return Response object
    }
);

// DELETE request
Router::connect("/create", array("http:method" => "DELETE"),
    function($request){
        // Do something and return Response object
    }
);

// Allow POST or PUT::
Router::connect("/update", array("http:method" => array("POST", "PUT")),
    function($request){
        // Do something and return Response object
    }
);

You can also use named parameters which accessible via $request.

Router::connect("/hello/{:name}", array("http:method" => "GET", "name" => null),
    function($request) {
        $name = $request->name ?: 'World';
        return new Response(array('body' => "Hello {$name}!"));
    }
);

Finally you can also use pattern:

Router::connect('/user/{:id:[0-9]+}', array("http:method" => "GET"),
    function($request) {
        $id = $request->id ?: 0;
        return new Response(array('body' => "Id: {$id}"));
    }
);
Conditional Routing

In lithium, you can access all properties of request object. This allow you to do conditional routing (in fact, RESTful routing are conditional routing).

// Only match if on the dev server and GET request:
Router::connect("/secret", array("http:method" => "GET", "http:host" => "dev.application.com"),
    function($request){
        // Do something and return Response object
    }
);

// Only match if request is over HTTPS and GET request:
Router::connect("/admin", array("http:method" => "GET", "env:https" => true),
    function($request){
        // Do something and return Response object
    }
);
Passing

You can punt processing to the next matching route by returning false.

// If $name is not jamal, pass it to next route
Router::connect("/guess/{:name}", array("http:method" => "GET"),
    function($request){
        $name = $request->name;
        if($name == 'jamal') {
            return new Response(array('body' => "You can guess my name.!"));
        }
        return false;
    }
);


// Match every access to /guess/*
Router::connect("/guess/{:name}", array("http:method" => "GET"),
    function($request){
        return new Response(array('body' => "Try again!"));
    }
);
Filters

Man, filters in Lithium are awesome. You can filter almost everything.

use lithium\action\Dispatcher;

// Filter all request
Dispatcher::applyFilter('run', function($self, $params, $chain) {
    // Do something before
    $result = $chain->next($self, $params, $chain);
    // Do something after
    return $result;
});

// Filter GET request
Dispatcher::applyFilter('run', function($self, $params, $chain) {
    if($params['request']->method == 'GET') {
        // Do something before
    }
    $result = $chain->next($self, $params, $chain);
    if($params['request']->method == 'GET') {
        // Do something after
    }
    return $result;
});

// Protect some routes from unauthorized user
use lithium\action\Dispatcher;
use lithium\net\http\Router;
use lithium\action\Response;
use lithium\security\Auth;

Dispatcher::applyFilter('run', function($self, $params, $chain) {
    // First, define our list of protected actions
    $blacklist = array(
        '/users/report',
        '/users/home'
    );

    // Inspect the request to get the URL for the route the request matches
    $matches = in_array(Router::match($params['request']->params, $params['request']), $blacklist);

    // If this is a match, check it against an Auth configuration.
    if($matches && !Auth::check('default', $params['request'])) {
        // If the Auth check can't verify the user, redirect.
        return new Response(array('location' => '/users/login'));
    }

    // Important: return the results of the next filter in the chain.
    return $chain->next($self, $params, $chain);
});

Thats it. I’m out of gas.

Update 1: Fix error in named parameter and passing example.

Update 2: I have created a simple example. Read about it here.

Notes

  1. muslihzarth reblogged this from jamalsa
  2. arantaweek reblogged this from jamalsa
  3. abagail-woods reblogged this from jamalsa
  4. ariela reblogged this from jamalsa
  5. malonko55 reblogged this from jamalsa
  6. jamalsa posted this