Intro to the MVC Pattern

There's a lot of talk these days about design patterns. The most talked about pattern in the realm of web development seems to be the MVC pattern, or the Model-View-Controller. It is this pattern that many of the most popular frameworks are built around. Frameworks like symfony, CakePHP and CodeIgniter enforce this pattern and offer tools to help make using it a breeze. Ruby's famous Rails framework and Perl's Catalyst also make use of the MVC pattern. So what is the big deal? Should you care? In this post I'm going to briefly try and explain the MVC pattern, why you should use it, and how.

What is What

The MVC pattern is made up of three separate parts -- the Model, View and Controller. In this section we'll explore each part and what they are supposed to do.

The Model

The Model is the thing that takes care of the data in your application. It offers ways to find and retrieve data, ways to save data, etcetera. In a lot of cases your model might be a simple class that is just a map of a database table. Many of the web frameworks like symfony give you tools to automatically generate a PHP class that has all of the properties and methods for any particular database schema you have. For example, a users table might have a corresponding User class with methods like User::findByUsername() and User::setEmail().

The important thing is that you encapsulate the domain logic. Sometimes all the model needs to do is retrieve rows from a database or read data from a file. Other times additional processing may be needed, like calculating the users age based on a birth date.

The View

The View takes the data from the Model and displays it in a useful way. In web applications this usually means that the data from the Model is displayed in an HTML page. Some other Views might be for generating an RSS feed or data for a web service. By separating the Model and the View, you can easily switch things up to create new interfaces to the data without much work at all.

Note that keeping the Model and the View separate does not mean that you can't get direct access to the Model itself. In many cases you will be using the Model directly. To output a users username you might use the Model and call User::getUsername() and output it. The idea is only that you separate the domain logic from the presentation. For example, you might have some sort of subscription service. If you wanted to output a message when the users subscription is expired it might seem logical to do something like this within the View:

  1. Welcome back, <?php echo $user->getUsername(); ?>!
  2.  
  3. <?php if ($user->getSubscriptionExpiry() <time()): ?>
  4.     Your subscription has expired. Please renew.
  5. <?php endif; ?>

This is mixing domain logic with the presentation. You are hard-coding what "expired" means directly into the View. If a time came when you needed to change the criteria for when a user is considered expired, then you'd need to go back into every file and change this hard-coded definition. Instead, you should create a method in the Model:

  1. class User {
  2.     // ....
  3.  
  4.     public function isExpired() {
  5.         return ($this->getSubscriptionExpiry() <time());
  6.     }
  7.  
  8.     // ...
  9. }

The Controller

The Controller is the part that connects the Model and the View so they can work together. Each part should be quite separate. That is, the Model should not have any code in it for outputting HTML (or any presentation) and the View shouldn't worry about things like fetching results and calculating user expiration dates. Since the two are completely separate for the most part, you need a Controller in the middle that connects them and makes the whole shebang work.

The Controller takes data such as input and works with it. In web apps this usually means taking information from the URL or forms, processing it, and then outputting a web page as a result. For example, if a user wants to update their email address then the the Controller will take the new email address from the form input, use the Model to update the record in the database, and then show a success page to the user using the View.

Here's how a request might be handled:

  1. A request comes in
  2. The controller looks at the incoming data like the query string or form data
  3. The controller might need to work with the model to fetch the requested data or to update it. For example, using User::findByUsername() to search for a particular user or User::setEmail() to update an email address.
  4. Then the controller invokes the view to output a result. This might be a page with all the information for the requested user, or a success page after the email address was saved.

What Is Each Part

We've explored what each part should do, but you still might be confused as to what each part actually is. Is it a file? A class? What?!

The thing is, the MVC is only a patten. There is no single right way to implement it. A Model is can be a single class that encapsulates all the work needed. But by no means does it need to be a single class. It is not uncommon for a Model to consist of multiple classes. For example, one class that is responsible for encapsulating the data and working with it, and another class that is responsible for actually fetching the data. A lot of the time one Model may depend on another Model to satisfy related data like connecting a web order to a user account that made the order.

The Controller is just a single class at it's most basic form. You might have a single class and each method is defined to handle one type of request (list users, edit user, search users etcetera). But again, it is not uncommon for a Controller to be made up of several different parts.

The View can be almost anything. In web applications it is usually a template that is evaluated with data gathered by the controller. You can use simple PHP files like demonstrated earlier, or a template system like Smarty.

The important part of using the MVC pattern is just the way that all these parts are separated form each other.

Why

Why use this pattern? At first glance it seems like it's a lot of extra work. If you wanted to make a list of users for example, then a simple list_users.php script that does a database query and outputs some HTML seems like it should take 15 minutes. If you use the MVC pattern, you'll have to think about creating the model first, and then the separate template files for the view, and then you have to worry about the controller to glue them together.

All valid points. It is true that the MVC pattern requires a bit more work. But as soon as you have laid down the foundation, it will make your life so much easier. While some changes may require edits in each part, like a dramatic change to the model might need changes made to the controller and view, you'll also get away with other changes more easily (remember our user expiration example?). More then that though, by keeping these three parts separate you allow yourself the possibility to interchange them. For example, using just one single model you can easily create a number of different interfaces to the data. Imagine how easy it would be to create an HTML page, an RSS feed and an XML data provider. In fact, all three of these things might even share a common Controller and only use separate Views. Adding a web service to interact with the data is as simple as creating a new controller to handle requests.

Try the MVC for your next project, you'll be glad you did.


Did you enjoy this post? Why not leave a comment below and continue the conversation, or subscribe to my feed and get articles like this delivered automatically each day to your feed reader.

Trackbacks & Pingbacks

[...] MVC with Zend Framework is quite easy. Here's a brief overview of each part and how they relate to each other. [...]


Comments

I mostly use the MVC style for Windows applications; it's interesting to see it applied through PHP in a web server context.

But this (or some variation) is really the only way to build a non-trivial application. What you're describing is a bit of a variation on what I've used, but it seems like a lot of that is the stateless nature of the web.

This is a very nice article. I especially liked the last section pertaining WHY should MVC should be used. A good MVC approach can leave your code loosely coupled, and you did a good job explaining that with the subscription example.

I look forward to more articles by the infamous Nadeau.

I'd like to say that Compass component framework is a good point to start with. It combines MVC and IOC patterns.

Haha...by MVC I totally thought you meant motor-vehicle crash. I've never heard of this acronym. Thanks for the explanation!

I have read some other articles on the same topic and your article blows them away. I am going to now build all my large applications this way. Great idea. I sort of used it before, but you explained it much better and now my brain just clicked with all sorts of possibilities.

I have been using a similar pattern as an MVC ... just didnt know i was doing this ... somehow every article i read on MVC made me think of this elaborate and complex scripting pattern that was to evolved for me :). Youre article is very well written ... thank you for your article.

Leave a comment

Line and paragraph breaks automatic, e-mail address never displayed, HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(required)

(required)