Practical PHP Patterns: Page Controller
Join the DZone community and get the full member experience.
Join For FreePage Controller is a subpattern of the Model-View-Controller one, where every logical page has a correspondent PageController that produces a response dynamically. Usually there are two collaborators that the Controllers calls methods on - a Model and a View. The Model's goal is executing business logic and providing data, while the View's one is to display it, possibly in different formats, and provide ways for interacting with the application to the user (such as forms and links).
History
Back in the time of when the web was starting out as a platform to consult remote documents (1990s), a path would have always corresponded to a static HTML document, which would be sent as-is to the client which requested it in the first place.
With the introduction of dynamic pages, a path did not translate to a single response anymore, but to an object capable of producing a response which can change everytime basing on parameters in the request, cookies or session variables. This dynamic generation of web pages is the basis of the Web as we know it today.
Implementation
Technically speaking, a Page Controller is an object (in the broader sense of the term, not ony an instance of a class but every kind of item) kept on the server, which is called upon a certain endpoint is the target of a HTTP request.
For example, plain old PHP scripts, which you call with Urls like /index.php, /list.php or /folder/member.php?id=42 are Page Controllers. But what is happening when you see Urls like /node/25645? Obviousy there is no 25645 file stored in the web server filesytem.
In more modern PHP frameworks, like Zend Framework or Symfony, the Page Controllers are not files but classes, a choice which simplifies the management of scope and the parameters passing to them (and also provides the unique possibility of defining multiple action methods). In this environment, Page Controllers are called Action Controllers or simply Actions, but don't be fooled by the name, since we have seen that even a simple PHP script is a Page Controller.
The reason for a different name can be tracked back to the transition from page-oriented websites to web full-featured web applications: a controller does not simply display a page anymore, but it performs some actions, at the end of which it can redirect the client or forward the execution to a colleague. The responses produced by controllers are not only HTML pages anymore, since they can be produced as HTML fragments, XML or JSON results.
Similarly, the plain old Page Controllers based on a PHP file have greater responsibilities than modern Action Controllers. Page Controller have to deal with the basic infrastructure of the programming language, like $_GET and $_POST, while Action Controllers are passed an higher-level abstraction like a Request Zend_Controller_Action_Request object.
The insulation layer between the client and Action Controllers will be the subject of another article. In general, this layer is not needed if the translation between URLs and Page Controllers can be performed natively by the web server.
Collaborators
The two collaborators of the Page Controllers have various implementation, which will be treated in detail in the upcoming articles of this series.
The Model part is the most application-specific part of the code, and contains as usual the business logic related to the domain. Ideally it should be testable in isolation, while the Page Controllers job is translating HTTP requests to method calls on the Model's objects and adding some indirection to check the client's authentication and authorization.
After having obtained the necessary data from the Model, the Controller uses a View component to generate the response. In PHP scripts, this separation is almost non-existent, as the script executes its logic and then starts printing. In Action Controllers, which are modelled as classes, they actually forward, automatically or not, to a View, which in turn may be modelled as a PHP script (Zend Framework's case) or as an object.
Examples
There are two simple examples we can made about Page Controllers.
The first one is a plain old PHP scripts, a solution widely employed before the advent of web frameworks. The mapping of the request to the file is performed by the web server, which takes the standard output of the script, along with its produced HTTP headers, and sends it back to the client.
<?php
echo '<p>Hello, ' , $_GET['name'], '</p>';
Very simple, and it's why PHP is so diffused and easy to use. But it does not scale.
A more sophisticated example is an Action Controller of Zend Framework. Here the framework, basing on configuration, figures out which controller is responsible for a request, and produces Zend_Controller_Action_Request and Zend_Controller_Action_Response objects as an abstraction over standard input and standard output. Part of this abstraction already existed in PHP ($_GET, $_POST) as an advantage over CGI scripts, part of it (matching Urls with predefined formats or regular expressions) is implemented in userland PHP by the framework itself.
class FooController extends Zend_Controller_Action
{
public function barAction()
{
// assign a variable to the view, with the value coming from somewhere
$this->view->variable1 = ...
$this->render('viewName'); // executes views/scripts/viewName.php
}
public function bazAction()
{
// other action related to the former
}
}
For a full discussion of Zend Framework's implementation of this pattern, refer to the manual.
Opinions expressed by DZone contributors are their own.
Comments