Model View Controller(MVC) in PHP

The model view controller pattern is the most used pattern for today’s world web applications. It has been used for the first time in Smalltalk and then adopted and popularized by Java. At present there are more than a dozen PHP web frameworks based on MVC pattern.

Despite the fact that the MVC pattern is very popular in PHP, is hard to find a proper tutorial accompanied by a simple source code example. That is the purpose of this tutorial.

    The MVC pattern separates an application in 3 modules: Model, View and Controller:

  • The model is responsible to manage the data; it stores and retrieves entities used by an application, usually from a database, and contains the logic implemented by the application.
  • The view (presentation) is responsible to display the data provided by the model in a specific format. It has a similar usage with the template modules present in some popular web applications, like wordpress, joomla, …
  • The controller handles the model and view layers to work together. The controller receives a request from the client, invokes the model to perform the requested operations and sends the data to the View. The view formats the data to be presented to the user, in a web application as an html output.

The above figure contains the MVC Collaboration Diagram, where the links and dependencies between figures can be observed:
mvc-collaboration

Our short php example has a simple structure, putting each MVC module in one folder:
mvc-structure

Controller

The controller is the first thing which takes a request, parses it, initializes and invoke the model and takes the model response and sends it to the presentation layer. It’s practically the liant between the Model and the View, a small framework where Model and View are plugged in. In our naive php implementation the controller is implemented by only one class, named unexpectedly controller. The application entry point will be index.php. The index php file will delegate all the requests to the controller:

	// index.php file
	include_once("controller/Controller.php");

	$controller = new Controller();
	$controller->invoke();

Our Controller class has only one function and the constructor. The constructor instantiates a model class and when a request is done, the controller decides which data is required from the model. Then it calls the model class to retrieve the data. After that it calls the corresponding passing the data coming from the model. The code is extremely simple. Note that the controller does not know anything about the database or about how the page is generated.

include_once("model/Model.php");

class Controller {
     public $model;	

     public function __construct()  
     {  
          $this->model = new Model();
     } 
	
     public function invoke()
     {
          if (!isset($_GET['book']))
          {
               // no special book is requested, we'll show a list of all available books
               $books = $this->model->getBookList();
               include 'view/booklist.php';
          }
          else
          {
               // show the requested book
               $book = $this->model->getBook($_GET['book']);
               include 'view/viewbook.php';
          }
     }
}

In the following MVC Sequence Diagram you can observe the flow during a http request:
mvc-sequence1

Model and Entity Classes

    The Model represents the data and the logic of an application, what many calls business logic. Usually, it’s responsible for:

  • storing, deleting, updating the application data. Generally it includes the database operations, but implementing the same operations invoking external web services or APIs is not an unusual at all.
  • encapsulating the application logic. This is the layer that should implement all the logic of the application. The most common mistakes are to implement application logic operations inside the controller or the view(presentation) layer.

In our example the model is represented by 2 classes: the “Model” class and a “Book” class. The model doesn’t need any other presentation. The “Book” class is an entity class. This class should be exposed to the View layer and represents the format exported by the Model view. In a good implementation of the MVC pattern only entity classes should be exposed by the model and they should not encapsulate any business logic. Their solely purpose is to keep data. Depending on implementation Entity objects can be replaced by xml or json chunk of data. In the above snippet you can notice how Model is returning a specific book, or a list of all available books:

include_once("model/Book.php");

class Model {
	public function getBookList()
	{
		// here goes some hardcoded values to simulate the database
		return array(
			"Jungle Book" => new Book("Jungle Book", "R. Kipling", "A classic book."),
			"Moonwalker" => new Book("Moonwalker", "J. Walker", ""),
			"PHP for Dummies" => new Book("PHP for Dummies", "Some Smart Guy", "")
		);
	}
	
	public function getBook($title)
	{
		// we use the previous function to get all the books and then we return the requested one.
		// in a real life scenario this will be done through a db select command
		$allBooks = $this->getBookList();
		return $allBooks[$title];
	}
	
	
}

In our example the model layer includes the Book class. In a real scenario, the model will include all the entities and the classes to persist data into the database, and the classes encapsulating the business logic.

class Book {
	public $title;
	public $author;
	public $description;
	
	public function __construct($title, $author, $description)  
    {  
        $this->title = $title;
	    $this->author = $author;
	    $this->description = $description;
    } 
}

View (Presentation)

The view(presentation layer)is responsible for formating the data received from the model in a form accessible to the user. The data can come in different formats from the model: simple objects( sometimes called Value Objects), xml structures, json, …

The view should not be confused to the template mechanism sometimes they work in the same manner and address similar issues. Both will reduce the dependency of the presentation layer of from rest of the system and separates the presentation elements(html) from the code. The controller delegates the data from the model to a specific view element, usually associated to the main entity in the model. For example the operation “display account” will be associated to a “display account” view. The view layer can use a template system to render the html pages. The template mechanism can reuse specific parts of the page: header, menus, footer, lists and tables, …. Speaking in the context of the MVC pattern

In our example the view contains only 2 files one for displaying one book and the other one for displaying a list of books.

viewbook.php

<html>
<head></head>

<body>

	<?php 

		echo 'Title:' . $book->title . '<br/>';
		echo 'Author:' . $book->author . '<br/>';
		echo 'Description:' . $book->description . '<br/>';

	?>

</body>
</html>

booklist.php

<html>
<head></head>

<body>

	<table>
		<tbody><tr><td>Title</td><td>Author</td><td>Description</td></tr></tbody>
		<?php 

			foreach ($books as $title => $book)
			{
				echo '<tr><td><a href="index.php?book='.$book->title.'">'.$book->title.'</a></td><td>'.$book->author.'</td><td>'.$book->description.'</td></tr>';
			}

		?>
	</table>

</body>
</html>

The above example is a simplified implementation in PHP. Most of the PHP web frameworks based on MVC have similar implementations, in a much better shape. However, the possibility of MVC pattern are endless. For example different layers can be implemented in different languages or distributed on different machines. AJAX applications can implements the View layer directly in Javascript in the browser, invoking JSON services. The controller can be partially implemented on client, partially on server…

    This post should not be ended before enumerating the advantages of Model View Controller pattern:

  • the Model and View are separated, making the application more flexible.
  • the Model and view can be changed separately, or replaced. For example a web application can be transformed in a smart client application just by writing a new View module, or an application can use web services in the backend instead of a database, just replacing the model module.
  • each module can be tested and debugged separately.

The files are available for download as a zip from http://sourceforge.net/projects/mvc-php/files/mvc.zip/download

Did you enjoy this tutorial? Be sure to subscribe to the our RSS feed not to miss our new tutorials!
... or make it popular on

148 Comments

  1. Great tutorial!
    I’m kindda new to mvc and oo, I really enjoy learning new stuff.
    I would like to make a login(DB) page and add,edit new records (CRUD) based on this tutorial, does any one wants to give me a hand? I’m working on CRUD right now,
    so if you’re interested in continuing this tutorial, please post here or email me at meegloz at myopera dot com.
    Maybe we can post the final work here, :)

    Thanks!

  2. This is a great tutorial. I have to disagree with “admin” that you should not jump into MVC using what you learned in this tutorial. Granted yes, you still need more, like an understanding of database interaction, but I think it is a much better stepping stone to try to make some basic projects with a self-created basic MVC framework rather than overwhelming yourself with a more professional framework that may even be overkill for what you need.

  3. Thank you so much for the excellent tutorial.

    I’ve been designing a site while using your tutorial as a reference, and I’ve hit a gray area with respect to the relationships among the components when lets say the view contains an html form that uses POST. Should the action attribute be set to the controller or index.php?

    Also, assuming you POST directly to the controller, if there’s a cycle where the controller includes the view and the view POSTS to the controller, how can one keep the relative paths in order.

  4. Thanks a lot mate :)

    Could you please write more articles about the MVC pattern please.

    Thanks again

  5. Hello,

    Thank you very much for such a lovely example but m able to run it..
    I kept the mvc folder in my htdocs & called index.php but it directly
    shows the content of index.php rather than showing books list.
    Any help will be appreciated.

  6. This guide is what I’m looking for. So far I got it from framework and need more for my student, I learn much from this. Thank you very much.

  7. In the book class, the attributes have public access. It is good practice to make these attributes private and have public accessors, e.g. public getTitle(), getAuthor() and getDescription(). However, once this is done, the views, e.g. booklist.php would need to use these methods. I have read in other MVC posts and tutorials that only “simple php” should be used in views. Is the passing of objects to views and the use of more complex php access methods acceptable?

  8. Thank you very much,this is a nice tutorial.The code in view module needs a little explanation i.e how you call the $title in view.

  9. Interesting very clear, but what about setting and getting how can I implement it? in other tutorial they say set and get is very important Im confused :(

  10. @Gammerz
    1. First of all this is just an introduction to MVC framework in PHP. Some things might not be the same in “real life”.
    2. I don’t find any reason for which not to use getters/setters in views. This refers to the principle of encapsulation and should be generally valid regardless the layer where you are. Further more if the same object is used in 2 layers encapsulation should be used to a achieve a better degree of decoupling.

  11. Excelent tutorial, easy to understand and with actually working code.
    This is the best simply-tiny MVC project on the web, the second is KissMVC. It would be great, if someone create next episode of this, with real basic examples of use (or sharing his little project).
    I need create similar framework for my bachelor work, or use this.

    (sorry for my English, i’m from Czech Republic – Central Europe).

  12. You really make it appear so easy along with your presentation however I find this topic to be actually one thing that I feel I’d by no means understand. It kind of feels too complicated and extremely broad for me. I’m taking a look forward on your subsequent post, I will attempt to get the grasp of it!

  13. Nice Tutorial!!thanks

    This is actually what I am looking for, not an MVC tutorial around the net which has a lot of nonsense blah blah and you got nothing..

    Thanks!

  14. good but i have few question
    i make a class with name menu. I make three properties and constructor. now i make another class with name model_menu.I want to create my menu class object in model_menu class constructor with value..see below code

    class menu{
    public $a;
    public $b;
    public $c;
    function construct($a,$b,$c){
    some code
    }

    class model_menu{
    public $model_menu;
    function construct{
    i wanna call object of first class here with value of three parameters.
    }

    thanks
    Regard

  15. Great tutorial, however I have one question..

    When you use the controller to tell what model what data to give you, how can you pass two different objects back to the controller at once if with return?

    For example in the controller I have buildProfile($userId) and I wish to get $user = new user(); return $user->getUsername(); but I also want to get $comments = new interface(); return $comments->getComments();

    Would it be okay to run both from the controller one after each other or is this missing the point of mvc?

  16. Thanks, this is best simple MVC tutorial which is i am looking for.

    Excellent job

    Thanks for sharing.

  17. Great tutorial, easy to understand, just what I was looking for. Sometimes is hard to find this kind of explanations which you need if you’re kind of noob (like me)

  18. Thank you very much! Out of all the MVC with PHP explaination out there, I think this tutorial is the easy to understand.

    I really don’t like those emphasize too much on .htaccess, folders organization & superclass together into the tutorial. It just complicate things. Should leave the in depth detail of SEO, OO, layered architecture, theory of design pattern etc out.

  19. Is anyone else getting his error? Thanks. Scott U

    Fatal error: Call to a member function on a non-object in /data/webroot/webadmin/app/mvc/controller/Controller.php on line 17

  20. Thanks for this posting.the way in which it has been explained with a diagrammatic representation along with some relevant code is worthwhile.

  21. I appreciate this, MVC is like pulling teeth trying to adjust to- and my learning style is hands on and this tutorial fits the bill perfectly, thank you.

  22. Thank you for this clear, concise, simple overview. It is exactly what I was looking for. I’ve been coding PHP for about 13 yrs. I use Objects and Classes and DALs but I’ve never really grokked MVC, no matter how many other articles I’ve read. This hit it home with the exact level of abstraction I needed to start writing with MVC in mind (as opposed to just blindly bashing at code and using a hammer to make it fit into the file structure.)

  23. To Tom Quaile and Bruno Cassol:

    It’s so easy to criticize what others do and show off at supergenius … and just do nothing better than what is already done … 2 years later still waiting for their wonderful concepts better than this, for php, not for java … if we are here is because we DO NOT want anything to do with Java …

  24. Dear Sir/Madam,
    First and foremost I will appreciate You on writing this awesome tut.Really Speaking from the core of my Heart that i was searching for this from a very long time.Finally my search is over.My suggestion to all viewers is that if they don’t want to use any framework but want to use mvc this is the one of tut they should use.

    Thanks and Regards
    Jhon

Leave a Comment.