Transitioning from CakePHP to Lithium
For anyone following the CakePHP project, you likely already know about the Cake3 project spinning off and becoming a separate framework called Lithium (li3 for short). After a couple of months of testing the Lithium framework and using it for my current web development needs, I’m so encouraged by the experience and the results, that I had to suggest to my readers that they consider making the transition from Cake to Lithium. As the framework nears its 1.0 release, I expect the core feature set to include all of the essentials that we Cake users already enjoy, but with some significant improvements. For those that appreciate good code like good art, Lithium is clearly a step in the right direction.
So far, I’ve only had occasion to try out a few features, and the outcomes have already been promising. Here are differences I’ve picked up from how things are done in Cake.
Bootstrapping and Additional Libraries
Lithium’s way of bootstrapping the various libraries allow for various server configuration settings more easily than Cake. Rather than defining constants in the app/webroot/index.php file, server paths are stored in the app/config/boostrap.php file. Only two constants need changing if you adjust the folder structure on your server: LITHIUM_LIBRARY_PATH, which points to the core libraries directory, and LITHIUM_APP_PATH, which points to the application itself. Other core settings may be included in bootstrap.php; as good practice, I added
1 |
Lithium uses third-party libraries much more seamlessly than Cake. Before, the scripts would have to be included through a vendors folder and brought into the application using, essentially, an include-like function. What I had wanted was a little more flexibility for where third-party scripts could be stored, since the possibilities for what third-party scripts require, in terms of server configuration and installations, usually call for install paths very different from how Cake structures itself in the background. Lithium provides a configuration file, app/config/boostrap/libraries.php, which allows you to add libraries either with a require directive or by using its built-in Libraries class. I was able to drop the Doctrine ORM library in the app/libraries directory and bring it into my app with:
1 2 3 | Libraries::add('Doctrine', array( 'path' => LITHIUM_APP_PATH . '/libraries/doctrine/DoctrineORM-2.0.0/Doctrine' )); |
Easy enough!
Namespaces and MVC
How Lithium makes use of PHP 5.3’s namespaces improves the flexibility of building model and controller classes. In one app, I have a sheet music database that provides downloads to web users. On the home page, it provides a list of all the composers in the database and a list of the top ten most downloaded files. In Cake, to do this, the ComposersController class has two options to fetch those top ten downloads. One is to perform a requestAction call to the DownloadsController class. The other is to call its own model class and perform a bindModel on the Download model, then run a find method to pull the top ten downloads. This isn’t too difficult or bloated, code-wise, but notice how Lithium improves upon this scenario.
I simply add:
1 | use app\models\Download; |
to the ComposersController class, then run the find method like so:
1 | $downloads = Download::find('all', array('orderBy'=>'Download.downloads DESC', 'limit'=>10))->to('array'); |
One advantage here is that I don’t have to directly instantiate the Download model class in the controller; I simply call its namespace with the use method, and all of its methods are available to the controller. I don’t have to worry about table associations if I don’t want to. And, well, the code just feels cleaner and yet still adheres to the MVC paradigm that keeps the various classes abstracted from one another.
Console
When it comes to Lithium’s console, it’s just a fun piece of work, and much easier to implement than Cake’s Bake script, in my opinion. Because Lithium makes more direct use with its li3 console app, the integration with your application comes pre-built and ready to go. What I’ve always appreciated about Ruby On Rails and Symfony is their use of the console to automate development processes. But I’ve also admired Cake for not being overly tied down to the console that you must create a particular shell environment to get the framework to install easily. In fact, in my earliest days of web frameworks experience, this factor pulled me over to Cake in the first place; I had spent hours trying to get Symfony to run correctly in my local console environment, but Cake just worked after dropping the main folder into my server root. I didn’t care what core features Symfony offered at the time because I could get right to work in Cake without any headache.
Lithium, on the other hand, improves upon both of these paradigms of console development, if you ask me. It maintains the same drag-and-drop installation capabilities as Cake, but comes packaged with console features that rival Ruby On Rails and Symfony. (I realize, though, that I’m speaking of a framework that is currently at 0.6, so some of this is my own predictions of what will come through at the 1.0 phase.)
Getting li3 to run required a simple adjustment to my .profile file. I simply added:
1 | export PATH=/usr/lib/lithium/console:$PATH |
to my .profile (I have the Lithium core installed in my /usr/lib directory) and was able to call li3 in the terminal, and was in business. After following the Console Tutorial on the Lithium site, I had a numbers game up in minutes. In short, I created my own console class in the app/extensions/command directory and then ran it quite easily by pointing to the application with cd, and from there calling li3 numbers (numbers was the name of the console class). I didn’t have to add any flags to the command line, just simply browsed to the app folder, and li3 knew what to do from there. Now, obviously the numbers game is a trivial way of learning the capabilities of a shell environment for a framework. But the integration is such that I’ll be able to customize console commands to perform unit tests, populate the datasource with schematics, manage sessions, perform cron jobs, build custom classes automagically, and so on.
Datasources
I’ll admit that the hardest chapter to write for my Beginning CakePHP book was the one on datasources. This was simply because the documentation was sparse on even how to get datasources working, let alone explain a normative way for optimally doing so in the Cake environment. Since then, the documentation has gotten much better. Nevertheless, the datasource schema for bridging various sources favors a kind of database model, meaning, you still use the $useDbConfig property and define that value in the config/database.php file to attach a datasource to your Cake app.
Lithium, on the other hand, assumes wildly different ways of sourcing data to your app. In fact, it comes pre-built to handle cutting-edge datasources like MongoDB and CouchDB which require a little more flexibility to leverage their feature sets. It handles these sources not as databases per se, or as PDO abstractions, but as connections. This semantic difference actually amplifies the capabilities of the datasource structure because it further abstracts the way data is pulled, manipulated, and otherwise handled by the framework. Web services like the dozens Google and Facebook applications are providing all could interact with a Lithium app the same way a database would, without attaching duct tape here and there in your code base. This makes for leaner code, and above all, improves performance significantly.
Concluding Thoughts
Dedicating two months to Lithium after years on the CakePHP platform has made me a convert for one basic reason. In the end, they both will get it done, and will get it done well. But, to be honest, the experience feels different, and however else the pieces fall into place that make the two frameworks semantically and structurally different doesn’t really matter when push comes to shove. As a developer, I just want to enjoy coding and I want it to be lean and clean.
So it really has begun to feel a lot like my experiences on the Mac and PC platforms. On the one hand, the Apple paradigm fights vigorously to streamline the feature set and to zero-in on each feature as a unique contribution to the user experience. They are ready to scrap features if they have to in order to maintain an intuitive and clean experience because they know that in the end, the user has to come away with a positive and simple interaction with their software. But the Microsoft paradigm has always been one of amplifying the feature set as much as possible and creating a platform that cannot be brushed aside. They want to drag-race the competition and compete as a total platform, one that out-does everyone else’s feature set, though only recently are they working harder to focus on the user experience. (Check out The Marketing Playbook by John Zagula and Rich Tong for a detailed explanation of how Microsoft thinks about platform plays behind the scenes and demolishing competition through Windows integration.)
Cake has started to feel less clean and more like Zend Framework feels; chock full of features, but lacking in performance and rigorous streamlining of the core feature set. I give kudos to Garrett Woodworth, Nate Abele, Joel Perras, Alexander Morland, and David Persson for their vision for Lithium and encourage you to give their new rising-star framework a go.
Comments
Feb 4th, 2010, 5:44 am
Nice article! The console section didn’t convince me to convert but defenitely going to take a look at li3.
@rajib Cake 2 is PHP5 only and Cake1.3 is optimized but still backwards compatible.
And Nate (or other members of both OS projects) is not irreplaceable and shouldn’t rely on one member. Fortunately CakePHP didn’t and there was a lot of progress when Nate and the others decided to focus on Li3.
Feb 4th, 2010, 5:48 am
Don’t get me wrong, Lithium looks sweet, but in the interests of fairness, you can do the downloads thing in cake just the same way (actually 1 line).
$downloads = ClassRegistry::init(‘Download’)->find(‘all’, array(‘order’ => ‘Download.downloads DESC’, ‘limit’=>10));
As you can see, the only difference on the face of it is really just syntax.
Feb 4th, 2010, 7:09 am
like neil said, all is very similar. Like changing the cake setup to have cake in a separate dir and only having your app in webroot i normally do just by changing *one* CONST, and that is CAKE_CORE_INCLUDE_PATH in app/webroot/index.php
Feb 4th, 2010, 9:44 am
@Neil and dogmatic69:
You raise valid points about the similarities of the two frameworks. To clarify on your example, Neil, there’s no question that you can get that process done in one line in Cake, but the syntax and structure of the framework in doing so is precisely what I’m getting at. In other words, the integrity of the abstraction within the framework is reflected in the syntax, and if one has to invoke ClassRegistry, that in my mind demonstrates what I mean by duct taping code. The structure as is doesn’t allow for a smooth flow of the MVC, and so a supportive class is made to allow exceptions. Every framework will do this, no question. I just think the Li3 approach looks promising because of its syntactical and structural improvements, if that makes sense.
Schreck
Feb 4th, 2010, 9:53 am
Corrected link for lithium: http://lithify.me/
Feb 4th, 2010, 10:29 am
David,
Thanks so much for the post and the kind words. It’s great when we find other people who really “get” what we’re trying to do.
The opportunity to take our 5 years of lessons developing CakePHP and build something new from the ground up has just been amazing. Not only are we able to make most coding tasks simpler and more intuitive, we’ve also been able to pioneer new approaches to integrating other libraries, and introducing programming paradigms that are entirely new in PHP, and this goes to the core of every part of the framework.
In terms of integrating outside libraries, one of the most important ones are a developer’s applications themselves. With Lithium, you can extend or completely replace almost any class in the framework, usually with no code changes (i.e. no more having to change all your views from $form to $myForm). And the filter system (http://lithify.me/docs/lithium/util/collection/Filters), which is supported by over 50 different methods across the framework, allows us to completely do away with clumsy before/after callbacks, which means more power in more places with less overhead and API clutter.
I could probably go on for a while, but then this would turn into a blog post in it’s own right, and I’ll leave that to you. David, we’re really glad to have you in the community.
Feb 4th, 2010, 10:43 am
@Primeminister: I’m not sure what you mean when you say there was a lot of progress when Garrett and I left the project. Mark Story has been the principle developer of 1.3 for almost a year now, and nothing much has really changed in that respect.
And while I’m sure CakePHP 2.0 is going to be great, by the looks of it, it’s still a little ways off on the horizon: http://github.com/cakephp/cakephp2x/commits/master
Feb 4th, 2010, 10:47 am
@Nate: A pleasure to be in the community.
And I’d expect that no one would object to blog posts from the principal devs in the comment section :)
holger
Feb 4th, 2010, 2:02 pm
I’m doing the transition to the mothership – Ruby and Rails.
Cake had left its lead developer and it still supports PHP 4 and Lithium is in an early dev stage.
Lot to do (“get practice”) and lot to learn but I’m sure that Ruby is worth it.
Feb 6th, 2010, 9:22 am
@holger: Good luck with Ruby On Rails. It’s an excellent framework and worth your time. But I hope you’re not only transitioning to RoR because of Cake’s backwards compatibility; that just seems like overkill. And I believe PHP proved itself a robust web dev language before RoR was on the scene. In a sense, you’re moving away from the mothership… (But the RoR fanboys like to think of their darling as the only web framework worth using :)
Feb 7th, 2010, 12:22 am
@hogler everything about rails is like magic its n’t is? but what is the point as a developer without understanding the underline architecture of rails using it, we all are using it, but only few knows how this framework is gluing things with meta-programming. And its deployment is quite difficult if you are not using heroku. But i love PHP+cakePHP because of its easy to use,deploy and good benchmarking. No point of stop using PHP because Rails is sweet. Even dave thomas said its good to learn a new programming language each year.
Ceeram
Feb 7th, 2010, 2:47 pm
Nice post, hope to see some more on li3


rajib
Feb 3rd, 2010, 10:06 pm
I have not tried lithium yet. But looks real promising, I am confused about the future plans of cakephp core team without nate. Its getting heavy and still tries to support PHP4 which is unnecessary.
I wish good luck both of them… but really tied with cake cant try anything else right this time. If i try some thing else then cakephp it would be Symfony or Lithium for sure .