Understanding MVC: Coding

October 15, 2009 — 61 Comments
The Yii Book If you like my writing on the Yii framework, you'll love "The Yii Book"!
This entry is part 3 of 3 in the series Understanding MVC

In the first part on this series about the MVC (Model-View-Controller) design pattern, I discuss the individual parts and what they represent. In the second part, I layout some common conventions of MVC frameworks. Both of those posts lead up to this one, in which I want to talk about actual code. In my opinion, it’s not too hard to understand what MVC means, in theory, or to follow a framework’s naming rules, but then you start developing a project and can quickly become confused as to where you actually put your code.

The problem in properly executing the MVC architecture for many people is that it runs contrary to what they’ve done thus far. If you’re a PHP programmer creating a page that lists every department (in an employees-departments application), you’d likely have a PHP script that:

  1. Generates the initial HTML, including the HEAD and the start of the BODY
  2. Connects to the database
  3. Queries the database
  4. (Hopefully) confirms that there are query results
  5. Retrieves the query results in a loop
  6. Prints the query results within some HTML, perhaps a table or a list
  7. Frees the query results and closes the database connection (maybe, maybe not)
  8. Completes the HTML page.

And that’s what’s required in a rather basic page. Even if you use included files for the database connection and the HTML template, there’s still a lot going on. And if you link those department pages to another page that shows more information about the department, passing along the department ID in the URL, that other page will need to add some data validation steps. And if you have a page that both displays and handles a form, like for adding an employee, there’s way, way more code and logic to add. Not that there’s anything wrong with this, mind you—I still program this way  as warranted—but it’s the antithesis of what MVC programming is about. You can think of MVC programming like a pyramid, with the Model at the bottom, the Controller in the middle, and the View at the top. The code should be distributed appropriately, with most of it in the Model, some in the Controller, and very little in the View.

MVC Pyramid

From a programming standpoint, a View should do very little, mostly just echo out the values of variables. The most logic a View should have is using a conditional to confirm that a variable has a value before attempting to print it or creating a loop to print out all the values in an array. The View generates what the user sees, that’s it. The Controller has more logic and code to it, as it responds to user actions, and acts as an interface between Models and Views. But it’s a common mistake to put code in a Controller that should really go in a Model. A guiding principle of MVC design is “fat model, thin (or skinny) controller”. This means you should keep pushing your code down to the foundation of the application (aka, the pyramid’s base, the Model). In a post I saw about the MVC architecture, they describe the Model as “maintaining state” between HTTP requests. I think that’s a good way of describing it because it encompasses both stored data and processed data that doesn’t necessarily get stored. So a departments Model represents stored data that is added, updated, and retrieved in multiple requests, while a contact Model represents data entered by a user in a form, validated, and sent in an email.

(As a a complete aside, there are some very well done, very funny videos on MVC available at RailsEnvy.com. In particular, watch the ones called “Controller Obesity” and “Keeping Views Stupid”.)

So what does this mean in actual code? Well, to start, if your View contains more than echo/print, and the occasional control structure, you’re possibly doing something wrong. If you’re creating new variables in a View, you’re probably doing something wrong. In fact, so little PHP code goes into a View, that even printing out something in a loop is normally done like this, with the emphasis on the HTML:

<?php foreach($departments as $n=>$dept): ?>
<li><?php echo $dept->something; ?></li>
<?php endforeach; ?>

This is opposed to what one might do in a common PHP approach, with the emphasis on the PHP:

<?php
foreach($departments as $n=>$dept) {
    echo '<li>' . $dept->something . '</li>';
}
?>

Now the code in the Controller is largely about…um…controlling the action, i.e., delegating responsibilities and reactions, responding to user input, etc. Controllers are classes, filled with methods that do the actual work. The work is largely retrieving specific Models (e.g., one record from a table or every record), calling upon a Model to be inserted, updated, or deleted, and calling upon a View to be rendered. The Model does everything else, like running the actual queries, validating the data, and so forth. However, in a framework, most of that code is built into the framework itself, so you can call a save or delete method on a Model, but the Model itself doesn’t have any such method defined (the Model inherits those methods from a framework class on which it’s derived).

Going back to an employees-departments example, say you want the page that lists the departments to also display each department head’s name. Presumably the employee ID of the person that is the department head would be stored in the department Model, like employee #14 is the head of Human Resources. To start, the Controller retrieves all the departments using that Model (this is Yii framework syntax):

$departments = Departments::model()->findAll();

The $departments variable gets passed along to the View so it can print them all out. This is basic MVC using Yii where, again, the departments Model doesn’t actually define a findAll() method, it just inherits one.

Now you also need to find the department head’s name for each department so that the View can display that. To find that person’s name, you’d need to fetch an employee Model whose employee ID matches the stored ID in the department Model. Using the Yii PHP framework, that code is

$emp = Employees::model()->findByPk($dept->departmentHeadId);

There you’re saying that you want to find the employee Model whose primary key value is the same as the departmentHeadId value in a given department Model.

What you absolutely don’t want to do is run that code or any similar query in the View. Very bad! Now, you might be inclined to put that code in the Controller, but in order to do that, you’d need to loop through each retrieved department, fetch the departmentHeadId, find the employee with that primary key value, and then associate the retrieved info with the department. Or you could retrieve all the employees and have the View find the corresponding employee record. In either case, it’s way too much code and logic to be outside of the Model.

To be clear, Yii, and other frameworks, support joins across Models, so in Yii, you’d do this (after identifying the relationship between the models):

$departments = Departments::model()->with('employees')->findAll();

But if that wasn’t an option in your framework, or if the two Models didn’t have a real, defined relationship, you could add this method to the department Model:

function getDepartmentHead() {
    $emp = Employees::model()->findByPk($this->departmentHeadId);
    if ($emp) {
        return "$emp->lastName, $emp->firstName";
    } else {
        return 'unknown';
    }
}

Once this is defined, you still wouldn’t need to add any code to the Controller, you could just do this in the View, within the foreach loop:

echo $dept->getDepartmentHead;

As another example, say you want to display employees names in the format LastName, FirstName, or something more elaborate. If you write a method that does that, defined in the employees Model, you can call that method anywhere that uses an employees Model and that might require showing the person’s name. This would include the page that lists all employees, the page that shows the information for just one employee, and the page that shows the head of a department. For example, in the above getDepartmentHead() method, you could return $emp->getFormattedName().

Whew! So, per my usual habits, this post has become far longer than I expected. I hope that I achieved my goal of explaining MVC using real-world examples, in a way that illuminates and clarifies this approach. If I haven’t, let me know and I’ll expand upon this in a subsequent post. As a postscript, a few hours after originally posting this, I touched up the last few paragraphs, adding more code to better illustrate the point (perhaps).

If you enjoyed this post, then please consider following me using your favorite social media, the RSS feed, and/or by subscribing to my newsletter. Or go crazy, and buy one or more of my books . Thanks!

61 responses to Understanding MVC: Coding

  1. If you could explain in more detail how the Yii framework joins models. I really don’t understand how the following code works:

    $departments = Departments::model()->with(‘employees’)->findAll();

    • Of course. Okay, to fetch all of the records for a given Model, you use the code ModelName::model()->findAll(), so for departments that’d be Department::model()->findAll(). That code would retrieve every department (i.e., every record from the database table associated with this Model). Now, in the hypothetical department Model, there’d be a relations() method (this is a Yii convention) that indicates the relationship between this Model and any other. So the departments would be related to employees like so:
      'employees' => array(self::HAS_MANY, 'Employee', 'departmentId')
      That line gives the label “employees” to this relationship. The relationship itself is that each department (the current Model, that includes this code) has many Employee Models and that the departmentId in the Employee Model is used to make the association (again, this is all Yii syntax; other frameworks do the same thing but slightly differently).
      Once you’ve established that relationship, you can invoke the relationship label in your Model retrieval to fetch the related Model data:
      Department::model()->with('employees')->findAll();
      Conversely, the Employee model would indicate its relationship to Department:
      'department' => array(self::BELONGS_TO, 'Department', 'departmentId')
      So you could fetch the department info for each employee using:
      Employee::model()->with('department')->findAll();
      If there are multiple relations (e.g., a join across three tables), you’d do with(‘modelA, modelB’).

      I hope that helps and let me know if you have any further questions.

      • I believe I understand fetching and merging columns from the linked record in the case where the current records has a BELONGS_TO linkage to another.

        But what does the method call:

        Department::model()->with(‘employees’)->findAll();

        actually return? if you have 3 departments, each with 3 employees, does this return 9 objects (with the same department info duplicated three times for each department)?

        Thanks

        • Good question. It will return 3 objects, of type Department, with each object having an employees attribute, which represents the employees associated with that department.

          • Wooha! you are my hero Larry.
            only one comment from you is better than whole “Agile … Yii 1.1″ book.
            thank you :)

          • Very nice of you to say. Thanks!

          • I think I may be missing something. Each department has 3 employees: so the 3 objects would be referring to the 3 departments, right? Each object (department) has 1 employees attribute. Does this 1 employees attribute contain information relative to 3 employees ?

          • Kind of. Each department is represented as an object. That object has an attribute “employees”. That attribute is an array of three elements (if there are three employees in the department), with each element being an object of type Employee.

  2. Models Vs Controllers. Ive been giving this a go on a mini project I’ve been doing and I really like the concept of splitting up code like this. However I am struggling with what I should put into a model an what into a controller. At the minute I’m creating my own pattern called MV (Model View). I can’t find a use for the controllers. Is there a standard which people follow? Thanks.

    • Thanks for the comments but I’m not exactly following you here. The standard people follow, of course, is MVC, and the use of the controllers is to manage the whole process: respond to user actions, be the agent between the Model and View, etc. So a View should just be the display of data within HTML, with no, or practically no, logic. The Model is the representation of data, which also means the Model has to have the ability to create new records, save updated records, retrieve them, delete them, and so forth. But you have to have some other place that makes use of the Model and that functionality. Think of it, perhaps, like general OOP, where you define a class, and then another place creates an object of that class and uses it. That’s what a Controller does. You wouldn’t put the use of the Model into the Model.

      Say you have a Model for an e-commerce site that represents a product that can be viewed, “carted”, purchased, shipped, resupplied, sold at a discount, and so forth. That’s many different uses of the same Model, so you use a different Controller (and View) to handle the different uses. One Controller or one action of a Controller fetches a single product whereas another fetches all the products of a certain type and another fetches products that are similar to already “carted” products and another checks for products that are running low in stock. All of the necessary code and logic for all of those uses wouldn’t go within the Model, as the Model should be a basic unit, not a universal unit. Does that make more sense?

  3. Wow, Thanks Larry.
    I found your posts on MVC very useful as I’m starting up a project in Yii at the moment (I found your link on the Yii docs website if member serves me correctly).

    I remember going to Uni and having previously learnt assembly code programming on a PIC microcontroller, when their entire description of OO was barely 2 lines. I’ve since come to understand OO (wiki was to help), but MVC was still not a full fully formed concept in my head until reading the Yii docs, Blog example, and finally your blog.

    THANK YOU!!

  4. Many thanks Larry – this has helped me to get a handle on MVC architecture and what it looks like in practice.

    I, like Simon, am still a bit hazy on what goes in a Controller given that the code examples seem to be relevant to the Model and View parts. Please could you elaborate a bit more regarding the Controller part and provide some code examples which illustrate what one might typically put in a Controller. Thanks in advance.

    • Hello Clive. Thanks for the comments. Okay, I’ll discuss the shell of two Controller methods in a basic Yii application. First, there’s actionList(), which is used to list all Models, departments in this case:

      public function actionList()
      {
      	$models=Department::model()->findAll($criteria);
      	$this->render('list',array(
      		'models'=>$models
      	));
      }
      

      The actual method in Yii does a bit more (it allows for the creation of selection criteria and provides for pagination of the list) but the basic premise is that when the user’s on the page for listing all the departments (www.example.com/index.php/departments/list), all the Department Models will be retrieved, then passed to the list View where they’ll be displayed. So the user’s action invokes this method, and it acts as the “glue” between the Models and the Views.
      Here’s another example:

      public function actionCreate()
      {
      	$model=new Department;
      	if(isset($_POST['Department']))
      	{
      		$model->attributes=$_POST['Department'];
      		if($model->save())
      			$this->redirect(array('show','id'=>$model->id));
      	}
      	$this->render('create',array('model'=>$model));
      }

      This action is called twice (at least) in the process of creating a new record. In both cases, a new, empty Model is created. Then, if the form has been posted, all the data is fetched from the form and the Model is saved. Then the show View is rendered for the newly created record. If the form hasn’t been posted, or if the Model can’t be saved (because there was a validation problem), the create View is rendered, which is the form.

      Let me know if you still have questions. Larry

  5. Hi Larry, first of all many thanks for this introduction in MVC. I’m an absolute beginner with frameworks and the split concept. After having already read the docs on Yii I still had no clue. Right now I think I see little bit clearer. But no solution without the next challenge(s) ahead ;-)

    Scenario: I’m trying to do some kind of private finance app with an investment being tagged with several categories (short-term, long-term) and being of one of several investment types (shares, insurance). DB-wise general data resides in the investment (start and end date), type-specific data in an e.g. insurance table (insured person).

    Now, I have my DB set up and I’m wondering for what tables do I need which structure elements (model, controller)?

    **1. Categories/Tags** (n:m relation with investment via linking table)
    (a)You wrote that all data manipulation is done by the model. So, is it correct that for every table I have I should create a model?

    Looking at the Yii tutorial confuses me:

    protected function afterSave()
    {
    foreach($this->getTagArray() as $name)
    {
    if(($tag=Tag::model()->findByAttributes(array(‘name’=>$name)))===null)
    {
    $tag=new Tag(array(‘name’=>$name));
    $tag->save();
    }
    $this->dbConnection->createCommand(
    “INSERT INTO PostTag (postId, tagId) VALUES ({$this->id},{$tag->id})”)->execute();
    }
    }

    (b) In this example they actually do not create a Tag model, but address it with Tag::model(). How is this possible?
    (c) Would you suggest for my categories to create a model for the categories and the linking table or use plain SQL as done in the tutorial?

    **2. Types**
    Let’s assume I want to show a detailed view of an insurance with data all the way down to tiny and updated bits. What would you consider a clever way to include data from the specialized tables in a query?
    (a) One option that came into my mind is to create models for each special table and add a relation to the investment model.
    (b) So, insurance depends on investment. Adding options depending on the insurance and a current state depending on the option, am I right when I think of it as cascading relations defined in the respective upper level model?

    **3. Controller**
    Would you use more than one controller (investment) for it?

    Huh, sorry, seems it got longer than a usual comment. Please feel free to shorten/move/delete the post.

    Thank you in advance for your answers and general comments if you figured out more fundamental errors in my reasoning.

    • Yeah, this is a bit much to address in a comment. Why don’t you post this to the support forum (use the Newsletters, Blog, and Other Topics forum) and I’ll respond in detail there. Thanks!

  6. Hi Larry,

    thank you anyway. Moved the topic to the yii forum:
    http://www.yiiframework.com/forum/index.php?/topic/6175-db-structure-and-then/

    cheers
    Steffen

  7. Thanks a lot for the introduction to Yii and MVC. I’ve always felt restricted in a lot of ways with frameworks, but it seems like the best way to manage a large website.

    • You’re quite welcome. Thanks for the nice words. I’ve never been a huge framework person myself, but if you find one that works for you, there’s a lot to be said for it.

  8. Hi Larry,

    Thanks for the great overview. I’m new to MVC , so I’m still a little iffy on something. MVC seems great for data driven sites, but what about sites that are primarily based on unique content (other than the header, footer). In other words, informational sites that don’t have multiple records and wouldn’t really need a db at all. For example, a corporate, non-product site. All of the MVC introductions never mention that scenario. Would I just not use MVC in this case?

    • You’re quite welcome. Thanks for the nice words. I would start by suggesting that more sites might be data driven than you think. A blog is exactly what you describe: informational with unique content wrapped within headers and footers. Yet blogs rely upon databases and often MVC.

      I guess I would answer that MVC is almost always used if you’re using a framework and a dynamic language (like PHP or Ruby). MVC is never used if you’re just creating static pages in HTML. Those areas in between are fuzzy. I would say that MVC makes more sense that more complicated a site is, though.

  9. Hi Larry, thanks for the quick response. I think I should have been more specific, though. I’m actually going to start developing a non-db-record oriented site, and have been looking around at various frameworks.

    I guess what I’m most curious about is unique pages like the “about” page, home page, contact page, etc where data is generally fixed and not varied by post date, etc. In the MVC model, would I just have one db entry for each page (there would really never be more than one entry for these pages), or just hard code it all in the view? The former feels slightly excessive, but the latter feels contrary to MVC; thus, I am lost. Looking forward to your thoughts on the matter.

  10. Ok, so I went ahead and looked around at the included samples that Yii comes with, namely \demos\phonebook. It does indeed look like static content can just be thrown into the view (now you can see how newbie my perspective was). I was paranoid that to adhere to MVC best practice, I should have all the content in the db (the h1 tags, the p tags, etc.). Still interested in your feedback, if any. Thanks again.

    • Yes, you can create static pages in a view, like Yii does. Another good reason to look at as many examples as you can! I would follow that same practice, too, in your case.

  11. Good post. The one thing that’s really bad practice though is doing 2 queries to retrieve something that can easily be retrieved in 1 (as well as using ORM as its a real performance nasty). For example in the department head example if you retrieved 30 departments (with 1 query) you’d then be retrieving each department head individually, so 30 more queries = VERY BAD.

    The other thing to note, is that the real separation should be between the UI and business logic. The UI should further be separated into presentation and code (i.e. View and Controller). The Model, well that’s really the domain model or can be a wrapper for other stuff. There’s also the concept of Data Transfer Objects (e.g. associative Arrays) and ActiveRecord. For really simple stuff Active Record is fine, but for anything more complex with relationships it’s best to separate the two. I would recommend Patterns of Enterprise Application Architecture by Martin Fowler to anyone who wants to understand this better.

  12. Sorry for the late reply, thanks for the demonstration and all the MVC articles you have written, these really got me kick started, I’ve been using MVC like a maniac the last 4-5 months, I really can’t see any turning back to the dark side any time soon. I’ve been using smarty on a project recently which is quite nice it implements MVC rather well and really simplifies any code you have to put into a view (as you do). So its great if you have designers and developer working on the same areas of a site. Otherwise I would stick to your own simpler implementation.

  13. There are some things I don’t fully understand, so I’ll take an example which I think will clarify everything for me. Say I have a web page consisting of a form which takes a name as input, queries a database for that name, and returns the result. How would that be done using MVC? Thanks in advance!

    • The form would be the View, the Model would represent the database table, the Controller would manage the display and and handling of the form. The user input would be an instance of the Model.

  14. Ok, so let’s see if I got it: I have a controller called ‘CustomerController’, which has a method called ‘add’, and inside this method, there are many calls to the ‘Customer’ model. So if I want to sanitize the input and add it to the database, I don’t write the actual code inside the ‘add’ method, but rather call methods of the model, like Customer->sanitize($name), Customer->add($name), and so forth. Am I right, or am I missing something? Thanks in advance!

    • Well, for starters, I don’t see why a Controller method would have “many” calls to a Model. But, yes, code for validating and sanitizing the data would go in the Model and would be called automatically (within the Model) when the Model is saved (i.e., created or updated).

  15. “Controllers are classes, filled with methods that do the actual work.” – thanks for this sentence! Now it’s clear enough.

    • You’re quite welcome. Thanks for saying so!

    • I thought the Models are the actual classes. Like if you have a “contacts” object you would have a model which is a contacts class. The class would declare the variables for the contacts (such as first name, last name, phone number, email) and the class methods would be functions to add/create/update/delete contacts. The controller will call certain methods depending on the interactions happening within the view. I’m new to MVC so maybe I’ve got it totally wrong.

  16. Hi Larry, I must say i’m not too familiar with Object Oriented programming, so your example makes me wonder what is the rigth way to do things.

    You say that the method getDepartmentHead() returns “$emp->lastName, $emp->firstName” (a String)… shouldn’t that return $emp (The Object) and let the view then do

    echo $dept->getDepartmentHead->getFormattedName();

    Thanks for your great articles!

    • You’re welcome. Thanks again for the compliment. You could do what you’re suggesting and it’s not really a big deal, but you really want to put as much logic into the Model as possible. If you create a getDepartmentHead() method in the Model, then ANY view can retrieve the department head. If you write that code into a single View, you’ve only benefited that one View. The whole point of a framework and OOP is to make stuff easily usable everywhere.

  17. It seems the funny are no longer available at railsenvy.com but they are at their youtube’s channel http://www.youtube.com/user/envyads

  18. I really appreciate this article
    Thank you

  19. yeah, thanks a lot! It helped me much..

  20. Wow, I have not worked with PHP Frameworks and is kinda difficult for me to get used to this metholodogy, however your article seems to explain pretty well the concept of MVC, which is a Framework’s base as I concern. Now, if you have any recommendation for someone who has years of experience working with pure PHP to get into this new thing using Frameworks I would appreciate it so much. I will read every tutorial you have here cuz I think you are great making things clear, What else could I do? I’ll work with Yii and I’m building a pretty big project. Greeting from Venezuela, sorry for my English ;)

    • Thanks, Joel, for the feedback. I’m glad you like what I do. (And your English is just fine.) As for getting into frameworks with PHP, my recommendation would be to read my Yii tutorials, then come up with your own test project to implement in Yii to get a sense of it.

  21. Finally a serie about MVC which is very well written!
    Thank you Larry! You helped me, and sure lots of others, a lot by making this public…

  22. Hi Larry,
    I am very grateful for these tutorials and explanations as your words really help to explain detail. However, as someone trying to learn how to use Yii I’m still drastically confused on a lot of the minor details. I know enough of the MVC theory but am just having difficulty with the actual coding part. What Im looking for is a basic app like collecting input from one text box. I’d like to see the controller, model and view files for something like that without validation or extras.

    This is what I need to learn but don’t know how. Can you point me to a resource? No one seems to address just the basics. I’ve already read the two yii books out on the subject , all your tutorials, and the yii manual and I don’t see simple tutorials on things. Everything I’ve ready is flooded with abstract Yii objects, widgets, helpers and the code just doesn’t make sense in my head. Thanks again!

  23. Hi Larry, Great post… Thank you for helping me down this road (a very daunting looking road if I might add!).

    Please can you expand on what you said above :

    “In fact, so little PHP code goes into a View, that even printing out something in a loop is normally done like this, with the emphasis on the HTML”
    ……
    “This is opposed to what one might do in a common PHP approach, with the emphasis on the PHP:”

    Even after reading though everything, I still would see the code with emphasis on HTML option as being worse (messier, harder to debug, harder to read) than the PHP option? I can’t imagine coding like that in real life… Please explain a little more on why I should?

    • I’m not sure what else to say, exactly. You may need to to it for yourself to appreciate the difference. But I can add that the separation means that when you need to change the look of something, you can edit the HTML without hunting through lots of PHP code. And when you need to change the functionality, you can edit the PHP without dealing with all that HTML. The tradeoff is that you have to open and access more files, but you don’t have as much to deal with in each file. Again, seeing it for yourself may make the difference to you.

  24. The way you explain the MVC is pretty good, but one thing I still don’t understand: the difference between MVC and 3-tier-architecture, I have already done much research, but I haven’t understood it.
    Maybe you can explain it as understandable as you did in your article about MVC.

    • Thanks for the nice words and for the interesting question. The MVC architecture is a application development approach, with a focus on software. The 3-tier-architecture is a type of n-tier architecture where the focus is on breaking up parts of a system. This may be a matter of hardware, but not necessarily. So, as solutions to problems, the two are somewhat similar, but they’re solutions to different types of problems, if that makes sense.

  25. hi larry, thanks for the explanation.i’m new to php framework.but as i read more i tried to compare the php frameworks each and i got yii is a better framework. i really understand on what you say in the theoretical part , but i’m confused how to start programming on MVC.please could you help me more

  26. Thanks larry for this amazing post on MVC. It was really help full.
    I saw the slide show of yours on the web on “how to be a web developer”, i guess the heading is right. That was an awesome presentation by you. I aim to be as a good web developer like you. :-)

  27. Felipe Marcellino April 3, 2013 at 7:39 am

    Great explanation about the basic principles of MVC!

  28. whoop whoop I like it!

  29. Guillermo Villanueva March 22, 2014 at 5:40 pm

    Hello Larry, first thank you and sorry for my english.
    If i need a dept list with head names is possible in mvc, to get that directly from the db using a simple join?
    Thank you
    Guillermo

Comments are great, but I'd strongly prefer any requests for assistance get made in the support forums. Thanks!