2.4. Page Controller

At this point, the front controller has instantiated a page controller and called the fetch() method on it. The page controller now looks at the remainder of the URI, sets itself up, performs some action based on that URI, and then renders the results of that action into a response object. It returns that response object back to the front controller when done.

The page controller is the most complex part of the dispatch process, and has three distinct phases of operation:

  • Setup and loading,

  • running the action, and

  • rendering the results.

2.4.1. Setup and Loading

The __construct() method calls a _setup() method as its last command; you can place customized setup code there. This setup code will be executed before loading the page controller with information from the URI.

When the front controller calls the fetch() method on the page controller, it passes the remainder of the request URI. (The front controller will have stripped off the first path-info element, since it has been used already to determine which page controller to instantiate.) The first thing the fetch() method does is to load up the properties of the page controller object based on the URI.


This is the name of the page controller as taken from the URI; is set by the front controller when the page controller is instantiated. For example, the URI path /blog/read/123/foo would result in $_controller = 'blog' in a page controller class of Vendor_App_Blog.


The first remaining element in the URI after the front controller has stripped off the page controller name. For example, the URI path /blog/read/123/foo would result in $_action = 'read'. This translates into the page controller calling the actionRead() method.


This is an array of the remaining path-info elements after the action. For example, the URI path /blog/read/123/foo would result in $_info = array('123', 'foo'). These will be passed to the action method as parameters via call_user_func_array(), so you don't need to access them directly.


This is the value of the format extension on the last path-info element of the URI, but only if that format will be recognized by the action method. If the format is not recognized, it will be appended to the last $_info element instead. (You can tell a method to recognize a particular format extension using the $_action_format) array, where the key is the action name and the value is an array of recognized format extensions).

For example, take a URI of /blog/read/123/foo.rss. If $_action_format['read'] = array('rss'), that means the actionRead() method should recognize the rss request, and so you will get $_format = 'rss'. But, if $_action_format does not have that entry, $_format will be empty, and the actionRead() will be passed parameters of ('123', 'foo.rss') instead of just ('123', 'foo').


This specifies what layout template name to use in the 2-step view process. When $_format is non-empty, $_layout will be set to null automatically. This is to indicate that a non-standard format is being requested, such as XML or RSS; the views for these non-standard requests generally do not need a layout wrapped around them.


This is an array of the query terms and values from the incoming URI. For example, the query string ?foo=bar&baz=dib would become $_query = array('foo' => 'bar', 'baz' => 'dib').

2.4.2. Running the Action

Here is a brief outline of what occurs when running the requested action:

  • The _preRun() method is invoked, which may change the properties as loaded by the above setup logic.

  • The _preAction() hook runs. (In the next step, the action method might _forward() to other actions, so this hook will execute each time forwarding occurs.)

  • The action method itself runs, using $_action to determine which method that should be, and using the parameters from the URI as stored in $_info. (This is where the center of the logic for the action is written by the developer.) For example, given a URI of "/blog/read/123/foo", the system will end up calling Vendor_App_Blog::actionRead('123', 'foo').

  • The _postAction() hook runs. (In the previous step, the action method might have called _forward() to other actions, so this hook will execute each time forwarding occurs.)

  • Finally, the _postRun() method is invoked, which may change the results of the properties as manipulated by the action(s).

2.4.3. Rendering the Results

Here is a brief outline of what occurs when rendering the results of the requested action:

  • The _setViewObject() method sets up a Solar_View object for the rendering process. In doing so, it adds the template path stack for views and a stack of class prefixes for view helpers. It also injects some special variables into the view, to wit: $controller_class, $controller, $action, $layout, $format, and $errors.

  • After the view object is set up, the rendering process calls the _preRender method so you can modify the view object or the page controller properties before rendering occurs.

  • The page controller assigns all of its own public properties to the view object, so they are available within the template.

  • If a view template name has been set in the $_view property, the page controller calls fetch() on the view object using that template name. This processes the template and returns its output. The output is captured into the page controller's $_response->content property. (This is the first step of the two-step view process.)

    [Note] Note

    By default, the value of $_view will be the same as the action method; e.g., if the action method is "actionFooBar", then $_view will be "fooBar". This means the template script should be named fooBar.php.

    If a recognized format has been specified, the format extension comes before the .php part. For example, if $_format = 'rss', the render process will look for a template called fooBar.rss.php. This means you can use the same action method to build a response for many different views of the same data.

  • After the view (if any) has been rendered, and if a layout template name has been set in the $_layout property, the page controller will re-use the view object (with all its variables and helpers) to render the layout. It does so by setting the template path stack to use the layout templates, and injecting the existing $_response->content into the proper location in the layout. The result then replaces the existing $_response->content, thus accomplishing the second step of the two-step view process.

  • The render process now sets the content type of the $_response object based on the value of $_format and the mappings of the $_format_type array.

  • Finally, the rendering process calls the _postRender() method, so that the contents of the $_response object can be manipulated as needed by the developer.

2.4.4. Returning the Response

The page controller portion of the dispatch cycle is now complete. It returns the $_response object to the front controller, which returns it to the bootstrap script, which sends it the client by echoing it.