web development articles and portfolio

Custom PHP MVC Tutorial: Part 3, Controllers

Posted on 14-10-2011

The controller classes in our custom MVC framework are the directors of our show. They get content from our models (writers?), and instruct our views (actors?) what to display. Even directors have orders to follow from above, however, and so do the controller classes in our MVC framework, in the form of a BaseController class they extend/inherit from.

In our Loader class from part 2, we had a validation routine which made sure the class of the controller being requested has a parent class of "BaseController". The purpose of this check was to make sure the class we're initiating as our controller object is guaranteed to have the properties and methods that every controller should have (as is the nature of inheritance in OO programming). Which properties and methods are those, you ask? Here is a look at the BaseController class:

abstract class BaseController {
protected $urlvalues;
protected $action;
public function __construct($action, $urlvalues) {
$this->action = $action;
$this->urlvalues = $urlvalues;
}
public function ExecuteAction() {
return $this->{$this->action}();
}
protected function ReturnView($viewmodel, $fullview) {
$viewloc = 'views/' . get_class($this) . '/' . $this->action . '.php';
if ($fullview) {
require('views/maintemplate.php');
} else {
require($viewloc);
}
}
}

Firstly, you'll notice this is defined as an abstract class - this means that an instance of the BaseController class can't be created directly; it can only be extended/inherited by other classes. We also defined the construct method here, which takes the action and URL values (as seen in the Loader class in part 2) and keeps a copy in properties of the object, when the object is created. Doing it here saves having to do it in every controller class.

There are two other methods defined - ExecuteAction and ReturnView. As you may have guessed, ExecuteAction executes the method/action being requested, the existence of which we confirmed in the Loader class in part 2. It is in these methods, which are defined in the individual controller classes themselves (which we're getting to shortly), where we call the ReturnView method to render our view, passing in the view data and a Boolean value on whether we want to render the full template or not.

This forms the BaseController class, and the properties and methods all controller classes in our framework need at a bare minimum. The classes we write for the actual controllers should now extend this class. Here's an example of a Home controller class which does just that (this would exist in /controllers/home.php):

class Home extends BaseController {
protected function Index() {
$viewmodel = "Just a basic string";
$this->ReturnView($viewmodel, true);
}
}

This is an extremely basic controller class, but it shows all we need at this point. As you can see, we are extending (PHP's form of class inheritance) our Home controller from BaseController, and we define a method called "index". In this method we create a string in the variable $viewdata, and we pass this to the ReturnView method. The variable we pass to ReturnView could be anything - an array, even an object - but a string will do for now. We also pass a Boolean value, which as mentioned above determines whether to show the full template or not for this action. In this case, we want the full template.

It may not seem obvious at first, but up until this point in our 6 part article on creating a custom PHP MVC framework, we have basically completed all the steps necessary for the framework to handle the request http://domain/home/index (or just /home, since our URL rewriting only requires a controller be specified, and our default value for the action variable in the URL is "index", as defined in our Loader class). However, nothing will be rendered in our browser - we still need our View to do that. Before we get too far ahead of ourselves though, let's not forget about our good friend, the model. Whilst technically not required to be separated from the controller, the model is at its highest level of usefulness when it is out in a class of its own.

Part 1 - Introduction
Part 2 - URL mapping and index.php
Part 3 - Controllers
Part 4 - Models
Part 5 - Views
Part 6 - Where to now

Social

Tags

Comments

comments powered by Disqus
groundwork