Chris Tankersley

Playing with Lithium

Posted on 2010-11-25

Since my day job was generous enough to give me the entire week off (as a reward, thankfully not a "Don't bother coming into work next week, or ever" kind of thing), I decided that I would spend some time looking at a new framework. I haven't looked hard a new framework since I really started working with Zend Framework a few years ago. I decided to take a look at Lithium, an up-and-coming 5.3 only PHP framework.

Why Lithium (li3)?

li3 was designed from the ground up to take advantage of PHP 5.3's new features and, at least coming from Zend Framework, has a much different workflow. It represented the biggest change in working with code compared to what I looked at as mostly syntax changes that frameworks like Kohana or CodeIgniter presented.

Filtering System

The filtering system allows for code to be modified on the fly without having to go in and modify the base class. The example on the Filters example page illustrates this: (modified below to what I ended up using):

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

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

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

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

The idea is that you have a base class, you apply an additional function to a method, and let the system handle it from there. The above filter will run when the Dispatcher::run() function gets called. It will take the current URL, compare it to a blacklist, and either redirect to the login page or allow the user through. Most of the core code is filterable so extending it to fit a developer's need is easy.

It Really is a rad Framework

li3 is designed as a rad (Rapid Application Development) framework that just gets out of the way. For the most part, it did. The MVC structure is easy to pick up and there is a lot of magic that happens under the covers. Initially I had more trouble getting li3 and MongoDB to talk to each other (which ended up being a problem with the pecl extension), but once I did it was pretty easy from there. It wasn't much more complicated than Zend Framework and Zend_Application.

5.3 Makes it Nice

li3 uses many of the new 5.3 features that were introduced to PHP. Closures, lambdas, and namespaces are a bit part of li3. This will make it somewhat hard for new programmers to pick up, but li3 doesn't look like its targeting newbie developers (that's not a bad thing). You really have to know what you are doing and what the code is doing. That said, if a developer understands the new 5.3 features, they are all set.

MongoDB is Easy to Work With

Once I got my pecl problem worked out, interacting with MongoDB was a breeze. A quick read-up on how MongoDB works, and a download of MongoHub really helped to work with MongoDB. I had more issues understanding how MongoDB worked than how to get it to work with li3. They did an excellent job lowering the entry bar to work with non-SQL databases.

Downsides

As with everything, there are some downsides. These aren't enough to get me to not want to use li3, but it makes it hard for me to want to use in day-in-and-day-out.

It's Evolving Rapidly

My biggest complaint is the lack of tutorials. The Blog Tutorial is nice, but leaves out of a lot of what goes on under the hood. The overall Drafts project will attempt to cover all the aspects of li3, but I did find some of the code already out of date. A good example is the Dispatcher filter example that I highlighted above; as it turns out, the example code doesn't even work with the last release (0.9.9). @gwoo did have a point that IRC is always up to date, but getting answers on IRC isn't always the quickest.

Technical documentation is helpful, but tutorials really help speed up the learning process. This is a big thing that the Zend Framework guys are striving to fix with Zend Framework 2, so it's not just li3. This leads too...

Lack of Community Documentation (Or Maybe It's Hard To Find)

The website lacks in tutorials, so the next logical thing is to move to Google. Finding user generated tutorials or example code was very hard. Lithium is a pretty common term on the web, and searching for things like 'Lithium authentication tutorial' brought up things not related to li3 at all. I found some code, but there was still an overall lack of community chatter. li3 is young, but it is still discouraging.

Relational Databases are a Second Class Citizen

I got working with MongoDB very quickly, but my sample application (a basic Twitter clone) fell apart with the database structure pretty quickly. I decided to switch to MySQL. That switch was easy (changed a config file and created the database), but then found out there was no support for table joins natively in li3 (though it is coming soon).

@jperras pointed me to the li3_doctrine project. That worked pretty well... until I tried to authenticate to my test website. li3_doctrine doesn't seem to have code that supports the built in Form authentication in li3, and the one tutorial I found for using Doctrine 2 and li3 was out of date. That was discouraging.

Conclusion - li3 Has Its Place

If you want to use a NoSQL database like MongoDB, li3 gets you up and running very quickly. The overall code structure easy to use and a breath of fresh air. The IRC channel is helpful (they got me past the pecl problem) and is easy to talk to. The technical documentation is top notch as far as I'm concerned. Its actively developed and well designed.

If the relational database support was better and there were more code examples, I'd be more apt to use it more often. I'll probably pick it up again when the next release comes out, but for right now li3 will be regulated to just the times I need a NoSQL database.


Comments

Categories: PHP Programming

Tags: li3 lithium PHP