Out of the ashes of a severe personality clash in an open source PHP web application framework project rose a new framework proclaiming that it simply sucks less than all the others. Lithium, otherwise known as li3, is the latest PHP application framework to come onto the scene. I know what you’re saying. *Yawn*.
As far as I can tell, Lithium is trying it’s hardest to be fast, lightweight, and use all the features that PHP 5.3 has to offer. I am unable to use it at work for a variety of reasons (not stable, required PHP 5.3 only, Nate is always picking on me via IM) but I am more interested in the ideas that are coming out of it.
None of these are what I want to talk about. I want to talk about something that I feel is a very underrated part of Lithium, the ability to define filters. This is a concept that you find in Aspect-oriented programming, and one that I imagine most programmers have never considered. Here’s why I think it’s a big deal.
Most frameworks are designed around an OOP paradigm. Yes, some mix them together (I’m looking at *you* CodeIgniter), but by and large you get the job done by extending on a base model / controller / helper / whatever to create new functionality. Sometimes this is not avoidable. But what AOP says is that there is another way, a way that Lithium has adopted as well.
Hence the creation of “filters”. As far as I can tell (and I’m sure I will be jumped upon if I am wrong) the purpose of filters in Lithium is to allow you to add functionality without extending the class itself. When I saw that I immediately understood why that is so awesome.
The idea of callbacks is also very similar: if X happens, run code Y. A staple of jQuery, Rails and probably other projects I have forgotten to mention. The idea is still the same though. In Garrett Woodworth’s presentation about Lithium to the Orange County PHP Users Group he goes over some solid examples of filters including:
These filters remind me of behaviors in Rails (and in CakePHP as well) and makes me wonder if signals are the same thing in the Django world. All in all, this looks to me to be a better way to extend functionality than actually overriding existing methods or hacking at something deep inside a class. Figure out what functionality you want, figure out where it needs to be called, and add your filter.