Why I'm not a fan of frameworks (Programming)

Paul M. Foster (20 December 2010 03:48:31 Revised 20 December 2010 03:55:15)

Frameworks in PHP are all the rage. There is every kind of framework you could want, from the slim Codeigniter to the much more bulky Symfony. With each, you must learn which functions to call under which circumstances to create the effects you want. You must build your controllers and views and models, and the framework provides, well... a framework for working with the models, views and controllers you've built.

The problem is that I'm not convinced all this effort is necessary.

Back in the day, when I was writing C code, an application had control of the screen and computer for as long as you needed. A single application, for example an accounting application, could issue checks, log bills, maintain budgets, record journal entries and the like. One application which did anything germain to accounting and bookkeeping. This accounting application, written in C, would typically be a single executable file, once compiled.

Compare that with a PHP application built for use in a browser. The very nature of the HTTP protocol means that sooner or later, your "application" is going to forget everything it knows about itself. Once your page is displayed in the browser, and barring a lot of javascript magic, it's done its job. At most, it's waiting for your input. At which time, the page is designed to take the data you've entered and give it to a *different* application. Theoretically, with a PHP page, you could make it reentrant, so that the file which displayed the data is also the file that processes it and presents you with a "thank you" page or somesuch. But this can't go on forever. That one file C executable paradigm just doesn't work with the HTTP protocol.

Let's define an "application" as something which displays a page in the browser, and then, optionally, accepts limited input, and processes that input, presenting some sort of feedback about the process. Thats' about the full extent of what a single-file PHP "application" could do. Now, we could also define an "application" as something which does all the above, but presented in a variety of pages. Let's say it's an application designed to maintain your DVD library. There would be pages to enter in various studio names, film categories, actor and director information, and the DVD titles themselves. You'd have pages allowing the editing and deletion of all this information. You're looking at a minimum of probably twenty pages by the time it's all said and done. This could also be an "application". But this application still consists of single pages which are self-contained. The "Add DVD Title" page really does one thing and one thing only. The code you write for it does that and nothing else. It doesn't allow for edting or deletion of DVD titles. It doesn't allow for maintaining your file of directors. Because of the nature of HTTP, these files are confined to single operations. In a C environment, this would be like building separate executables for each function, and then stringing them all together with a single bash script or a single C executable which made a lot of exec() calls.

Maybe this lack of memory inherent in the HTTP protocol is the reason for the fascination with frameworks. After all, each file/page will have a lot of things in common with the other files/pages in a given "application". For example, all the pages will probably have a similar "look", dictated by CSS. They may all use the same basic routines to access the MySQL back end. They may all have similar validation routines for certain fields, like directors and actors. You can gather many of these things into libraries and classes. A framework facilitates simple access to these things.

I've investigated a few frameworks. I've looked into CakePHP, Seagull, Symfony, and a few others. I've coded some applications with CodeIgniter. I've even built my own framework, just to be able to look at the design decisions made by framework builders.

Here's an example. In CodeIgniter, if I want to use the validation library to ensure my users include a valid username on their forms, I'd do it this way:

$this->load->library('validation');
$rules['username'] = 'required';
$this->validation->set_rules($rules);

There is vastly more to fully using the validation library than this. There is more you can do with it, but I just want to confine the discussion to this one little piece of it. In order to make reasonable use of this library, I have to load it:

$this->load->library('validation');

Right off, I have a beef with this. Why not just say:

require_once(LIBPATH . 'validation' . '.PHP');

Or I could code some sort of function that loads the library, like this:

load_library('validation');

That function could snag the library path and the file extension and load the library, if it hadn't already been loaded.

Okay, what about the last part of it:

$rules['username'] = 'required';
$this->validation->set_rules($rules);

I set up an array of variable names whose values could include the word 'required'. Then I feed this to the validation library, which, I trust, will ensure that I don't get bogus information from my users. But again, I can do a similar thing this way:

if (empty($_POST['username']))
     raise_a_stink();

It's basic PHP. It's simple. It doesn't require a separate library file or two to be loaded. It doesn't require methods or methods of classes to be invoked. It doesn't require a lot of indirection.

Again, let me be clear: I'm not picking on CodeIgniter. I think it's one of the sleekest and simplest frameworks out there. I've used it, I like it, partially because of its simplicity.

But here's another problem. CodeIgniter is a pretty simple no-frills framework. It's got a front controller and all the other nifty things frameworks typically have. But like most frameworks, by the time you've displayed the page you want, you've called in 5-10 files just to show your "Add DVD Title" page. I could write this page without a framework and call maybe two files in. Result: far less complexity and far quicker load time. Most of my applications run on an internal network, so name resolution and other internet delays don't apply. And by actual tests, the pages I load without a framework load considerably faster than they do when using a framework. Imagine the effect when you factor in internet lag times as well.

So what does this added complexity buy me? In many cases, as illustrated above, not much. Some will argue that I could simply avoid the validation library and construct the validation as I did above. True enough. But if we're going to apply logic like that, where do I *stop* applying it? Do I really need a controller class to process my "Add DVD Titles" page? I could code this stuff myself. What about a front controller? Do I really need that? At some point, I've obviated the need for a framework entirely.

Let's take the front controller. A front controller typically loads configuration data, loads in universal libraries and functions, and passes control to the particular controller for your page, based on the attached query string. I get that. All this preliminary stuff is in one place, you don't have to write the same code for every page, etc. But what would happen if I put all that preliminary stuff in a file like "startup.php", and then called it at the top of every page I display? So instead of this:

index.php?c=dvd&a=add

I would write this:

add_dvd.php

And at the top of my add_dvd.php file, I'd include() my startup.php file. Ooh, you say, but now you have to remember to include this file! True. But otherwise, I have to remember to call the front controller (index.php) and feed it the controller (c=dvd) and the action (a=add) I want. Is there that big a difference?

I'm not using a lot of Web 2.0, javascript, Ruby on Rails stuff. As a C programmer, PHP fits my existing skill set, and does everything I need. My pages generally involve displaying some list from which the user can pick an item, filling in a form which will alter the database contents, etc. Nothing incredibly fancy. The amount of code in a typical page is on the order of a couple hundred lines of code, if that. I need multiple indirection, 10 files included and a lot of background logic for this?

Now, in some respects, I like the idea of breaking things down into components. For example, I have a couple of different "templates" for web pages. These generally enclose whatever page-specific content I have. So I separate out the "templates" from the page-specific HTML. Makes perfect sense. I can go in later and change the look and composition of the page template without altering anything else.

Similarly, model classes are sometimes a good idea. When working with a single table, I can build a class which contains all the methods I'm likely to want it to do: add_customer($params), update_customer($custno, $params), delete_customer($custno), and get_customer($custno). Then in the main file, I can simply instantiate the class, call the method with the appropriate parameters, and we're done. But I could also simply make it a file full of standalone functions. At the top of the file, I could instantiate the link to the database, and put a "global" variable at the top of every function to allow it to see the instantiated link. The only real difference here is that with a class, I can specify the visibility of the methods. But let's face it-- this model will serve maybe five to ten pages. Does it matter to me whether the rest of my "application" can see all the functions or not? Not so much. If some nutty programmer wants to take my standalone functions and abuse them and then claim he couldn't do that if they were in a class, well okay. I suppose. But it seems kinda silly to abuse the functions just to prove you can.

And yes, I've created code that will determine which database backend to use for this page, and use that one. Standalone code. Likewise, I built a separate login.php file which tests to see if a user is logged in first, and forces him or her to login if not. Also standalone, so I have to call it at the top of every file where I think security is important. If I didn't do that, and if I were working with a framework, I'd still have to do something like $this->check_security() in each controller.

I'm not trying to say MVC frameworks are all crap and useless. But I think in a lot of cases, they're largely overkill for PHP applications. And I particularly think that's true in my case, for my internal company applications.