What is MVC?
MVC is the idea that you have three different pieces that work in unison(simultaneously) to form a complex application. A car is a good real-world example of MVC. With a car you have two views: the interior and the exterior. Both take input from the controller: the driver. The brakes, steering wheel and other controls represent the model: they take input from the controller (driver) and hand them off to the views (interior/exterior) for presentation.MVC on the Web
The ideas behind MVC frameworks are quite simple and extremely flexible. The idea is that you have a single controller (such as index.php) that controls the launch of applications within the framework based on arguments in the request. This usually includes, at a minimum, an argument defining which model to invoke, an event, and the usualGET arguments. From there the controller validates the request (authentication, valid model, request sanitization, etc.) and runs the requested event.For instance, a request for
/index.php?module=foo&event=bar might load a class called foo and run foo::bar(). The advantages of this method include:- A single entry point for all applications.
- Removing the headaches involved with maintaining numerous scripts, each with their own relative paths, database connections, authentication, etc.
- Allowing the consolidation and reuse of code.
Why Create My Own MVC Framework?
This article doesn't really advocate "You should write your own MVC web framework!" as is tries to explain "This is how MVC web frameworks work in theory, and why they are so great."As of this writing, there are very few true MVC frameworks written in PHP. In fact, there is only one that I know of, Solar, that is entirely pure PHP 5 code. Another one out there is Cake, which is trying to be the "Ruby on Rails of PHP." I, personally, have a few problems with both of these frameworks. Both Solar and Cake fail to leverage existing code in PEAR, Smarty, etc. Cake appears a bit disorganized at the moment. Finally, Solar is the work of mostly a single person (not that Paul isn't a great coder or person, but there is only a single gatekeeper at the time of this writing). These may not be issues that concern you, and if they don't concern you, by all means check these two out.
Coding Standards
Before you start coding a cohesive framework, you might want to sit down with your team (or yourself) and talk about coding standards. The whole idea of MVC programming revolves around reusable and standardized code. I recommend talking about, at least:- What are your coding standards regarding variable naming and indentation? Don't start a holy war, but hammer out the basics and stick to them, especially when it comes to your foundation classes.
- Decide on a standard prefix for your functions, classes, and global variables. Unfortunately, PHP does not support namespaces. As a result, it might be a good idea to prepend your variables to avoid name collisions and confusion. Throughout this article, I've prepended my global variables, functions and classes with
FR_, so as to distinguish core foundation code from simple application code. - I highly recommend using phpDocumentor to document your code as you actually code it. I will document all of the core foundation classes as well as my initial applications in this article. At my own place of employment, I run phpDocumentor via a
cronjob to compile documentation frequently from my code repository.
Coding the Foundation
With all of that theory out of the way, here are the foundation classes. Be sure to read the comments for my reasonings, ideas, and implementation details. I'm presenting a combination of things I've done in the past that work for me, and the results of a few years of trial and error. By no means is this the only way to program an MVC framework, but I think it provides a good overview of how things should work.Filesystem Layout
The basic layout is simple and somewhat strictly defined. There is a directory for includes, which will follow a specific pattern to make it easy to use PHP's new__autoload() function. Another directory is for modules, which will have their own layout. The hierarchy looks like:- /
- config.php
- index.php
- includes/
- Auth.php
- Auth/
- No.php
- User.php
- Module.php
- Object.php
- Object/
- DB.php
- Presenter.php
- Presenter/
- common.php
- debug.php
- smarty.php
- Smarty/
- modules/
- example/
- config.php
- example.php
- tpl/
- example.tpl
- example/
- tpl/
- default/
- cache/
- config/
- templates/
- templates_c/
In the filesystem structure, all of the foundation classes live inside of includes/. The example laid out a sample module, as well. Each module has its own configuration file, at least one module file, and one template file. All modules reside in modules/. I've become accustomed to wrapping my modules in an outer-page template, which is what the tpl/ directory is for. Each "theme" or template group has its own template directory. For now, I'm going to use default/ as my outer-page template. Later I'll show how to create a presentation layer for modules that want to render themselves.