Tuesday, August 16, 2011

MVC in PHP

What is MVC?

This is a broad definition of the components as defined by the pattern. Later on I will describe variants of this but this is MVC as described by the original implementations in Smalltalk-80

The Model

In its simplest form the model stores data which is to be accessed by the view and written to by the controller.

The model is the most complex of all the parts of the system and will contain all the logic which is specific to the application and where domain entities which relate to real world concepts (such as "a user" or "an order") are stored. It is the part of the application which takes data (from any source) and processes it. The model also handles all data access and storage. It has no knowledge of any controllers or views which may use it.

For example, in PHP the model may represent a "User" in the system. It will handle any operations regarding users. Saving/loading records, validating registrations.

The model is not (common mistakes made by those misinterpreting the pattern):

  • A simple data access point
  • A class called "model" which represents a single database table

The View

The view contains all the display logic. In PHP it will be the part of the application which generates the HTML. It has direct access to the Model and can query the model to get its data. It can create callbacks to its controller (for example a clicking a button in the view would trigger an action in the controller).

The View is not (common mistakes made by those misinterpreting the pattern):

  • Absent of logic
  • Given data by the controller

The Controller

The controller takes user input and updates the model where required. Where there is no user interaction (e.g. where a static data set is displayed and will be the same every time), no controller should be necessary. It is important to note that the controller is not a mediator or gateway between the view and the model. The view gets its own data from its model. The controller accesses the model but does not contain any display logic itself. All the controller does is respond to user input.

Each controller is linked to a single view and a single model.

The Controller is not (common mistakes made by those misinterpreting the pattern):

  • A gateway/mediator between the model and the view
  • The place where views get initialised based on the state of a model. The controller is linked to a single view and responds to actions on it. For example a list of products would be a single view. The controller would handle user actions such as sorting the list, filtering the records it's displaying based on criteria specified by users. It would not also deal with displaying the info for a single product. This is a different view, which requires its own controller.

Program flow

The typical program flow in MVC is:

  • The model, view and controller are initialised
  • The view is displayed to the user, reading data from the model
  • The user interacts with the view (e.g. presses a button) which calls a specified controller action
  • The controller updates the model in some way
  • The view is refreshed (fetching the updated data from the model)

Hello World:

<?php

class Model {
public $text;

public function __construct() {
$this->text = 'Hello world!';
}
}


class Controller {
protected $model;

public function __construct(Model $model) {
$this->model = $model;
}
}


class View {
protected $model;
protected $controller;

public function __construct(Controller $controller, Model $model) {
$this->controller = $controller;
$this->model = $model;
}

public function output() {
return $this->model->text;
}

}

//initiate the triad
$model = new Model();
//It is important that the controller and the view share the model
$controller = new Controller($model);
$view = new View($controller, $model);
echo $view->output();
?>


Example 2 :


<?php
class Model {
public $text;

public function __construct() {
$this->text = 'Hello world!';
}
}

class View {
protected $model;
protected $controller;

public function __construct(Controller $controller, Model $model) {
$this->controller = $controller;
$this->model = $model;
}

public function output() {
return '' . $this->model->text . '';
}

}

class Controller {
protected $model;

public function __construct(Model $model) {
$this->model = $model;
}

public function textClicked() {
$this->model->text = 'Text Updated';
}
}


$model = new Model();
//It is important that the controller and the view share the model
$controller = new Controller($model);
$view = new View($controller, $model);
if (isset($_GET['action'])) $controller->{$_GET['action']}();
echo $view->output();
?>

No comments:

Post a Comment