nemetral.net | Insightful posts on design and code

July 31, 2008 · Category Patterns · icon13

A gentle introduction to MVC (part 1)

This article was written by nemetral.

Voices matter! Please feel free to share your opinion, ask for more explanations or point out divergences using comments.

No time to read this now? Bookmark it and come back later..

MVC is certainly the widest spread architectural pattern in today’s webdevelopment landscape. Brought back to fashion by Ruby on Rails from 2004 on, it has been translated and implemented into many languages and more than 100 web frameworks. This illustrated three-part is aimed at helping you cross the gap between a traditionnal vanilla PHP script and a full MVC implementation.

Part 1: decoupling a traditional webpage

Remember community.com? Here is what could be the server-side script used to generate a page featuring all the website’s members (assuming an average use & level of vanilla PHP):

<html>

  <?php include 'inc/header.php'; ?>

  <h1>Members of community.com:</h1>
  <?php
    // INITIALIZING THE DATABASE
    $connection = mysql_connect('host', 'user', 'password');
    mysql_select_db('database', $connection);
    // PULLING OUT THE DATA
    $data = mysql_query('SELECT name FROM members');
    // DISPLAYING THE DATA
    echo '<ul>';
    $i = 1;
    while ($member = mysql_fetch_array($data)) {
       echo '<li>Member #' . $i . ': '. $member['name'] . '</li>';
       $i++;
    }
    echo '</ul>';
  ?>

</html>

with inc/header.php being like:

 <head>
    <title>Community.com rocks!</title>
 </head>

Note: this is still very basic HTML without DOCTYPE

Since data is pulled out from the database in the middle of HTML tags, each time you need to display the members’ names, you need to rewrite the PHP/SQL snippet, which makes it more difficult for your code to be maintainted. Still, although not being a flawless, this is not dumb writing neither: we can see the ghost of a decoupling through the use of include, which makes it possible to start splitting the code into reusable parts (e.g. the header).

Here are a few things we could do to enhance the organization of this script:

  • remove all the PHP logic (e.g. querying the database, formatting data etc.) from in-between HTML tags and paste it all above the first <html> tag
  • use PHP variables (filled with the data pulled out from the database) to carry data in-between the HTML tags
  • step further in decoupling and split the script into two files: one for the logic and the other for the presentation (based on the PHP variables)

Here is a simple graph to better understand the process:

Step 1 is the original PHP script where business logic (which query to execute, pulling out data from the database etc.) is mixed with HTML tags. In Step 2, we isolate the logic at the beginning of the script, keep the HTML tags at the bottom of the script and link the two using PHP variables. Step 3 is the final step: we simply split the script in two files (one for the logic and the other for the HTML presentation). Applied to our code, here would be the result at step 3:

<?php
  $connection = mysql_connect('host', 'user', 'password');
  mysql_select_db('database', $connection);

  $data = mysql_query('SELECT name FROM members');
  $members = array();
  while ($item = mysql_fetch_array($data)) {
    $members[] = $item['name'];
  }

  include 'tpl/template.php';
?>

with tpl/template.php being like:

<html>
  <?php include 'tpl/header.php'; ?>
  <h1>Members of community.com:</h1>
  <ul>
  <?php foreach ($members as $i => $member) : ?>
    <li>Member #<?php echo $i + 1; ?>: <?php echo $member; ?></li>
  <?php endforeach; ?>
  </ul>
</html>

Note: when using PHP as a template engine (this is what we are doing in the second file), it is quite common to use alternative structures. Also note that I changed the ‘inc’ directory for a ‘tpl’ directory, the latter being in charge of gathering all template files (so tpl/header.php in step 3 is the same file than inc/header.php in step 1).

Once parsed, you will get the following HTML output (supposing there are only two members Anna and Lisa):

<html>
  <head>
    <title>Community.com rocks!</title>
  </head>
  <h1>Members of community.com:</h1>
  <ul>
    <li>Member #1: Anna</li>
    <li>Member #2: Lisa</li>
  </ul>
</html>

Let’s now zoom out from the script and have a look at the whole request/response structure. When calling http://community.com/members.php, here it what happens:

  1. members.php gets connected to the database, pulls out the members’ names and fills an array with them (called $members)
  2. members.php includes the template file in which $members is looped through so as to produce the final HTML

This could be called a View/Controller architecture, where members.php is the controller and tpl/template.php the view:

Proceeding like this makes it possible to separate logic from presentation: first we run all the queries and then we generate the HTML page using PHP variables.

(Go to part 2)

A comments thread is available on CodeIgniter Forums

Entries (RSS) Did you enjoy this post? Consider subscribing to the RSS feed!

11 comments · 2 pingbacks · Leave yours

  1. Veera
    August 1st, 2008
    1:17 pm

    Very simple and clear explanation.

  2. speedovation
    August 13th, 2008
    7:56 pm

    actually its more like normal php but it clears a lot of points.

  3. Pingback : http://h8ersclub.com/zend-framework-testing-day-2-time-to-read/
  4. Slavi
    December 5th, 2008
    5:55 pm

    Why are you reinventing the wheel ?

    Check this out:
    http://framework.zend.com/

  5. nemetral
    December 5th, 2008
    9:27 pm

    @Slavi: dude I’m not reinventing the wheel, I’m just explaining it! Zend framework is great, so is CodeIgniter, but new developers joining our collective MVC enthusiasm need simple, basic and clear guidelines to start with.. and that’s what I’m trying to achieve on this blog.

  6. Jaswinder
    December 6th, 2008
    3:59 am

    @Slavi

    That’s true but if a programmer don’t know the basics then they won’t understand Symfony at all. Using a framework and understanding how it’s done are different.

    Thanks nemetral for this tutorial. It helped me understand MVC a lot better.

  7. Willian
    December 10th, 2008
    2:14 pm

    Hi! This is great a MVC explanation! Thank you. Quoting your article, can I translate it to

    portuguese and add in my blog? (www.pequenotux.blogspot.com)
    A hug…

  8. nemetral
    December 10th, 2008
    10:33 pm

    @Willian: yes you can translate this article on your blog with due links to my original article. Thanks in advance!

  9. Willian
    December 11th, 2008
    7:56 pm

    Ok, I will. Thank you nemetral :)

  10. Willian
    December 13th, 2008
    1:40 pm

    Hi, I translate it (quoting this article :) and post in my blog. Thank you very much.

  11. Anthony
    March 3rd, 2009
    10:43 am

    Hi nemetral,
    Thank you very much. My understanding has been improved!

  12. chad lee
    March 28th, 2009
    6:54 pm

    Great tutorial and easy to understand. It would be interesting see an article on alternatives to the MVC pattern.

    My personal method:

    If a file is not found (not an image, css or javascript) then the URL path parsed to into a module/action file and parameters (interpreting the URL path anyway it wishes for a project). The module/action file is included from outside the webroot, which can include a template file to display results.

    I use a mini-frame with about 100 lines of code and it works great and completely flexible. I can add pages to a site by simply dropping in action files and giving them templates to include.

  13. Pingback : http://wcs.wayne.edu/blog/2009/12/19/friday-links-the-birthday-edition/

Leave a comment