Some people, when confronted with a project, think “I know, I’ll use a framework.” Now they have two problems.
I love frameworks. I stiil shudder when I remember the long days where I worked in spaghetti code when I first started programming. It was shortly into my first experiences with PHP that I was introduced to Zend Framework and the idea of an MVC design pattern that would keep my business logic, data access and html all in separate files. I seriously thought I’d found the best thing since sliced bread.
It was when I studying the MVC design pattern that I stumbled upon Rasmus Lerdorf’s post about “No Framework MVC” and realized that it was possible to create a well formed architecture without using a third-party framework. This naturally led to several projects I did in a bare-bones style without the use of an existing framework. Let me just say that it was a great learning experience. In the end, we switched those projects to Zend Framework because it brought a lot of needed tools to the table as well as a less buggy implementation of the core MVC framework.
When I came to my current position with Lendio, they were already using Kohana 2 so I learned a new framework, and to be honest I’ve been a pretty hard sell. I follow ZF bloggers, I prefer ZF’s conventions and general style, but I’ve come to appreciate K2 for the lightweight rapid application development tool that it is. K2 has been great, it allowed Lendio to roll out an awesome product on an unheard of timeline and its been stable since our launch so no complaints here.
But, even with as awesome as I’ve found both Zend Framework and Kohana to be, my projects have been far from painless. What I’ve found in each of my projects, whether it was my own framework or a third-party one, is that at some point someone made a choice (or an assumption) in the framework and that choice cost me time development time, headaches and in a few instances never-ending frustration.
One of the first I stumbled upon was using the Zend_Db Row Data Gateway implementation in a way that allowed one class (or table) to inherit from another class (table). One just has to look at the series of questions I’ve posted to stackoverflow about the topic to see that isn’t a really great solution to a lot of these issues. In the end, I had to roll a custom data mapper that could support inheritance between database tables as well as other more complex relationships between data.
When I first started working with K2’s ORM and Database Querybuilder, I kept running into this annoying situation where I’d start building a query for one thing and then I’d need to run another query to get some other piece of data, and pass that piece of data into the first query and then run the first query. But every time I set this up, one or both queries would fail. It wasn’t until I did some digging that we found out that the Querybuilder object actually wrote the query information into the Database driver and was flushed every time a query was run. There was no way to build a query in K2 and store it for later use. At first we just made sure that queries were built and run in proper sequence. Eventually it occurred to me that we could build a class that contain all of the necessary arguments for running a query in K2’s Database Querybuilder but would allow us to build a query and hang on to it, till we were ready to use it.
There are more times than I care to count where I’ve had to give up on using a framework tool because it just didn’t get the job done. Has anyone else tried to use Zend_Date::isValid()? As far as I know, it still takes any string and forces it into a valid looking date and thus always returns true. Or in the case of Zend_Db, there was a time that you could use named parameters when using the PDO database adapter library, but they removed it when they abstracted variable escaping into the framework and away from the native database driver. In K2’s case, have you ever tried to build an ACL or navigation tree based on controllers and actions? Maybe its my ZF background, but I figured that both shouldn’t be that difficult to implement either as ports from ZF or natively. However, since Kohana supports nested controllers, you couldn’t just work with a simple module/controller/action path. Implementing both the ACL and navigation tree in a more or less infinite architecture required tons of development time from our team. We’ve been live with our new site for several months now and just recently implemented a method call on a K2 helper that failed miserably in our live environment so once again we spent hours debugging through framework code only to find that our environment didn’t like the way it was done in the helper so we had to ‘massage’ the framework to do it a different way.
I know, you’re either annoyed because you get my point or because you’re wondering when I’ll make it. Basically, I think Terry Chay is on the money when he says that frameworks suck. And why do they suck? As Terry Chay put it: “It is not so much an assumption as a fact: when you develop software, it is about making choices. It is about tradoffs. You can do “A” but you can’t do “B.” “
He later says:
And why I mention this is because I want to mention that whenever I rail on Rails or rip on your framework, every criticism is coming from this concept of There are consequences. When you use a framework, you make a choice. When you adopt a framework, you adopt all the choices that that framework designer has adopted—so you have to be very careful in which framework you are going to use.
So frameworks suck because when you choose a framework, you’re locking yourself into a lot of choices that have just been made for you. And even worse is that you’re locking yourself into choices that you don’t even know were made, at least not until they bite you in the rear end. And that’s not even the worst of it, again I am going to appeal to Terry Chay:
It’s probably because framework code is the antithesis of the design principles that went behind PHP. Frameworks try to do too much; PHP tries to pass the buck. Frameworks are complete; PHP is a component (the ‘P’ in LAMP). Frameworks are standard; almost nothing in PHP is standard, that’s why you need a website to document its quirks. Frameworks surround; PHP sits inside. Frameworks are complicated; PHP is simple.
Like with Zend_Db and escaping values for queries, most frameworks end up doing stuff that is already done by something that actually did the job really well and all in the name of proper code reuse or keeping abstractions intact or some such nonsense. Maybe that works in environments and languages where the cheapest and fastest solution is code related. PHP, however, is a single component of an entire ecosystem and ultimately PHP programmers MUST be good at identifying the easiest, cheapest, and quickest way to deal with any given problem and frameworks in their completeness have a tendency to reduce our ability to do that.
But, if frameworks suck so bad, why are we here on a blog for another PHP library / framework / thing? And why is everyone, including me, still using frameworks in PHP? And is it possible to have our cake and eat it too? Please stay tuned for our next article in this series about reinventing the wheel.