Pragmatic PHP MVC

A look into Model-View-Controller design patterns, Page Controller alternatives, and Intercepting Filters in PHP web applications.

Featured image for Pragmatic PHP MVC

I recently completed a project in PHP. It went quite well, but I was still keen to improve on my design methodology. To a weekend coder this may seem unnecessary, but the bigger applications you write, the more consideration you’ll find yourself putting into the design to prevent headaches later.

Specifically, I was interested in MVC (Model-View-Controller) programming, as I was looking to reduce the repetition of code involved in generating other views in my web application (such as generating PDFs). So, I’ve been hanging around application design forums and reading up on software patterns to glean information.

A whole new vocabulary opened up to me. It was a bit daunting at first, but I wholeheartedly recommend learning at least some of it. The “pattern” names themselves are essentially just ways to easily identify abstract coding methodologies so everyone knows what they’re talking about. Basically, this allows developers to drop acronyms like “MVC” into normal conversation, even though it in itself isn’t a single file, but an idea composed of three coding practices:

  • Model: Where all your “business” logic is stored.
  • View: How the output of the model is displayed.
  • Controller: The thing that glues the model and view together according to what the user wants.

Unfortunately, definitions like that are always up for dispute and alteration/addition, but essentially as long as you always keep in mind the goals behind code separation you can’t go wrong; as MVC is more a frame of mind than set-in-stone rules.

It’s best to keep a strictly pragmatic view when deciding what’s best for your application: just because something looks cool doesn’t mean it will instantly benefit you. Going back to my PDF generation problem, I wanted to use MVC so that I could:

  1. Generate raw output from my business logic (database queries and things).
  2. Give that to the appropriate view (according to the user request: HTML or PDF).
  3. Prevent repeating any business logic.

Which fits into the MVC paradigm nicely. Obviously, if you had a relatively simple PHP application, like a simple mailer, then you wouldn’t want to add all the extra MVC overhead. There’s a common joke in development that fits well here:

I once had a problem, so I decided to use MVC. Now I have two problems.

However, I tend to recommend leaning towards MVC as it simply means that your application will be more flexible if you want to include another view or interface to your system. This can be especially useful in web applications where you must keep up with the times to allow users to access your content in different ways, which we’ve seen with the advent of RSS and API endpoints.

Front Controller vs. Page Controller

Things are rarely a simple case of “decide and go with it,” as I found out while hacking on the backend to my latest website project. The problem I had was to do with the way I was handling user authentication through sessions.

Basically, I wanted something different from the Zend framework’s approach of routing all requests through one single file. I wanted to split up the Front Controller into smaller chunks. My gripes with a monolithic Front Controller are:

  1. Routing everything through one file creates a dependency on that file, which impairs the modularity of code. For instance, any new module would have to also implement the Front Controller pattern to be integrated easily.
  2. The Front Controller needs to know about every action the user could request, or otherwise it wouldn’t know what controller to dispatch.
  3. Leading on to this, it means the Front Controller would require some sort of data set that maps actions to controller files. As PHP initializes a fresh environment on every startup, this means that it will have to continually reload this data set, which would grow in size in proportion to the application, making it a potential bottleneck.

My approach to solving this was to look at the Page Controller pattern:

“The Page Controller has one input controller for each logical page of the Web site.”

However, that approach generated some problems for me. The reason that the Front Controller is a popular pattern is that you can call Intercepting Filters. Without them:

  • I was getting code duplication by having my Page Controller also deal with the whole process of authentication. Each additional Controller page would also need all this code.
  • This in turn affected the Page Views; I needed to create views to send out all the authentication messages.

Intercepting Filters

Fortunately, I managed to implement a system that uses Page Controllers with Intercepting Filters. The filters run before the main page logic, checking session variables.

Instead of having the Intercepting Filter classes output anything directly, my current system checks the authentication status and, if the user is unauthorized, performs a header redirect to a page more suited to dealing with the task (such as a login page).

When the system is all up and running, I’ll share some of the code snippets here.