Geoff Groberg

A Custom MVC Framework

As a grad student, I discovered that the systems designed for student equipment reservations were not very good, and way too expensive. So I built EQ Checkout.

I debated whether to use an off-the-shelf framework, like Laravel, Django, or Rails. But in the end, nerd that I am, I built my own framework. It’s based in PHP and inspired by various things I’ve seen in other frameworks. It’s simple, easy to deploy to an inexpensive LAMP stack, and cleanly separates MVC code.

Some Interesting Things About the Framework


The framework has a database abstraction layer, so it can use MySQL, PostgreSQL, and other DBs. But I chose to use SQLite for this app. WHY?! Why would an experienced web developer use SQLite for an application that’s designed to scale? It’s super fast. It’s easy to deploy. It’s stable. And for other reasons.


EQ Checkout is a multi-tenant application. Using SQLite made it trivial to silo off data for each tenant. They each get their own, completely separate database. Easy to do, easy to maintain and make backups.

You might be concerned about high traffic and concurrency, but it’s not an issue with an app like this. Since each tenant has their own, separate database, each database has a relatively small number of users. Even if a tenant had 1000 times the number of users this app was designed for, concurrency still probably wouldn’t be an issue. And there would be other issues that came into play long before SQLite became the bottleneck.

An ActiveRecord-ish Model

I like short, efficient bits of code. Here are some examples of how the Models work in my framework:

Get a list of users:
$users = user::getList(); // returns an array of user objects

Get a user with a specific email address:
$user = user::get("WHERE `email` = ''");

Save a model (in this case a “reservation”):
$result = $reservation->save();

Delete a model:
$result = $reservation->delete();

You can also specify model relationships, like hasMany and hasManyThru. For example, a user can have many reservations. And a user also can have various roles, thru the userRole model:
public $_hasMany = array("reservation");
public $_hasManyThru = array(array("role", "userRole"));

There is also a simple way to define validations for each model. In this example, a user must have a name, and the name must be at least 2 words. (So “Bono” and “Sting” unfortunately can’t register as users.) Also, in this case, email is required, must be a valid email address, and must be unique (but case insensitive):
public $_validations = array(
"name" => array("required", "minWords,2"),
"email" => array("required", "email", "unique,CI"),

Of course there’s a lot more to the framework: a router with some sensible defaults, lots of convention of configuration, basically a lot of ideas I stole from Rails.

I have mixed feelings about the wisdom of creating your own framework, vs using an existing one. In this case, it worked pretty well. But moving forward, I’m interested in getting better with Rails. There are pros and cons of course. One good thing about using Rails, Django, or Laravel is that they come with so many features. And one bad thing is that they come with so many features.