Front/Action Controller and Template solution

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Hurreman
Forum Commoner
Posts: 61
Joined: Sat Apr 29, 2006 8:42 am

Front/Action Controller and Template solution

Post by Hurreman »

Hi everyone, it feels like ages since I posted on devnetwork, mostly due to my lack of time to actually code any php these days. At work I'm stuck with classic ASP and to some extent VB.NET, so lately I've felt the urge to keep working on some of my personal projects in php.

Since it's been a while, I've been reading up on old posts regarding mvc and front/action controllers, and I would now need some comments on how I setup my pages.
Would home.php be considered a controller, with the template acting as a view? I feel confused after not touching either oop or mvc for over a year.

default.php

Code: Select all

 
<?php
require_once("lib/FrontController.php");
require_once("lib/Locator.php");
 
$controller = new FrontController();
$locator = new Locator();
 
$controller = new FrontController($locator,'actions/','home','error','action');
 
$controller->execute();
?>
 
actions/home.php

Code: Select all

 
<?php
require_once('../lib/Template.php');
class home
{
    public function execute(){
        
         $tpl = new cTemplate('../tpl/base.php');
         
         $tpl->pageTitle = "This is the page title";
         $tpl->metatags = array('keywords'=>'php,mysql,apache,etc..','description'=>'a description..');
         $tpl->scripts = array('../js/jquery-1.1.3.1.js');
         
         $google = new cTemplate('../tpl/googleAnalytics.php');
         
         $tpl->googleAnalytics = $google->render();
         
         echo $tpl->render(); 
    }
}
?>
 
tpl/base.php

Code: Select all

 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
    
    <title><?php echo $pageTitle; ?></title>
    
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <meta name="content-language" content="en" />
    
    <?php
    // Print any supplied meta-tags
    if(isset($metatags))
    {
        foreach($metatags as $metaTag => $metaContent): 
        ?>
            <meta name="<?php echo $metaTag; ?>" content="<?php echo $metaContent; ?>" />
        <?php 
        endforeach; 
    }
    ?>
    
    <?php
    // Print any supplied javascript includes
    if(isset($scripts))
    {
        foreach($scripts as $script): 
        ?>
            <script type="text/javascript" src="<?php echo $script; ?>"></script>
        <?php 
        endforeach; 
    }
    ?>
    
</head>
<body>
 
    <?php if(isset($googleAnalytics)) { echo $googleAnalytics; } ?>
    
</body>
</html>
 
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

This is how i do mine:

index.php:

Code: Select all

 
<?php
// Error Reporting
error_reporting(E_ALL);
 
// Config
include('config.php');
 
// Maximum Execution Time;
set_time_limit(10);
 
// Security
ini_set('register_globals', 'Off');
 
if (ini_get('register_globals')) {
    exit('Error: register_globals is enabled!');
}
 
include_once(DIR_LIBRARY . 'system/controller.php');
include_once(DIR_LIBRARY . 'system/front.php');
include_once(DIR_LIBRARY . 'system/action.php');
include_once(DIR_LIBRARY . 'system/model.php');
include_once(DIR_LIBRARY . 'system/router.php');
include_once(DIR_LIBRARY . 'application/registry.php');
 
// Registry
$registry = new Registry();
 
// Config
$config = $registry->get('config');
 
// Database     
$db = $registry->get('db');
 
// Settings
$settings = $db->getRows("SELECT * FROM setting");
 
foreach ($settings as $setting) {
    $config->set($setting['key'], $setting['value']);
}
 
// Response
$response = $registry->get('response');
 
// Front Controller
$controller = new Front($registry);
 
// Dispatch
$controller->dispatch(new Router('common/default', 'index'), new Action('error/error_404', 'index'));
 
// Output
$response->output();
?>
 

controller/default.php:

Code: Select all

 
<?php  
class ControllerCommonDefault extends Controller {
    function index() {
        $this->document->setTitle('Home');
        
        $this->id       = 'content';
        $this->template = 'common/default.tpl';
        $this->layout   = 'common/layout';
        $this->children = array('module/navigation');
                
        return $this->render();
    }
}
?>
 
User avatar
Hurreman
Forum Commoner
Posts: 61
Joined: Sat Apr 29, 2006 8:42 am

Re: Front/Action Controller and Template solution

Post by Hurreman »

Thanks, it's always nice to see that others have come to similiar solutions :).

I think I'll have to delve deeper into some other frameworks (I've mostly been looking at skeleton lately) to see how their forwarding/chaining works, since that's something I feel that my code is lacking so far.
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Re: Front/Action Controller and Template solution

Post by Kieran Huggins »

Chris Corbyn had an excellent post about the front controller pattern (searching....)

found! http://w3style.co.uk/a-lightweight-and- ... -for-php-5
Last edited by Kieran Huggins on Tue Jun 24, 2008 10:09 am, edited 1 time in total.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Front/Action Controller and Template solution

Post by Christopher »

Fascinating seeing this code. They are almost identical and very good examples of current best practices. I don't think either example is MVC (in the pattern, not framework sense), but given the simplicity of the examples that is understandable. I think in PHP you don't always want to have strict separation in the Presentation layer. So you end up with "Controllers" that are almost all display code, because that is about all there is in many PHP pages.

The title of the thread probably more closely describes what is probably pretty close to the current gold standard for PHP ... which I will call FACT after the title. Using Front/Action Controllers is a great way to organize your application. You get some centralization benefits for things like clean URLs, configuration and Access Control. And the Action Controller give you a nice sandbox to put you application code by wrapping it in support code to make repetitive stuff easier. It also provides a convention to naturally separate using PHP as a programming language from using PHP as a templating language.

View/Controller separation is a pain unless you have sufficient complexity to get some benefits from reuse. But it seems like the current practice in PHP is to mostly turn View/Controller into Two Step View like shown above -- which makes a lot of sense. blueyon actually builds some nice View functionality into the "Controller" with a little layout capability which is very handy.

Also, not much above about Models and the Domain, which is probably a growth area for PHP designers in the next few years.

One challenge we have in Skeleton is abstracting out some of the things you see built into the code above. How can you allow both easy Actions like Hurreman shows that allow more traditional PHP usage. And optionally allow the layout help that blueyon shows that eases the tedium of page building. But not require either, so you can use one style or the other, or mix-and-match. A lot of PHP is loading stuff and assembling it into a Response, so you want to streamline that process as much as you can. But is there a way to do that without going full-stack with the tight integration and conventions that implies? I'm not sure...
(#10850)
User avatar
Hurreman
Forum Commoner
Posts: 61
Joined: Sat Apr 29, 2006 8:42 am

Re: Front/Action Controller and Template solution

Post by Hurreman »

Kieran Huggins wrote:Chris Corbyn had an excellent post about the front controller pattern (searching....)
Yep I found that a few nights ago (actually still have it open on a tab in Firefox), and found it interesting and educational. I had for example never seen extract() being used, and it sure saved me some headache since I had been thinking of doing something similiar for my service locator! I'm gonna take another look at his post and see if I can get any ideas for action forwarding.
arborint wrote:Fascinating seeing this code. They are almost identical and very good examples of current best practices. I don't think either example is MVC (in the pattern, not framework sense), but given the simplicity of the examples that is understandable. I think in PHP you don't always want to have strict separation in the Presentation layer. So you end up with "Controllers" that are almost all display code, because that is about all there is in many PHP pages.
Thanks arborint, I'm glad to hear that I've at least managed to follow some best practices. And I suppose it makes sense that controllers and views don't get separated too strictly in a web application. Perhaps I'm not making a good example of MVC, but that's fine with me. My goal is to make my life as a web developer easier by using better and reusable code, and most of all I wanted to make sure that I was heading in the right direction.
arborint wrote:Also, not much above about Models and the Domain, which is probably a growth area for PHP designers in the next few years.
I didn't include any Model code since it's all basically a database layer for me, where I've structured it into various different Models for Users, Groups, Forum-posting and whatnot.

Overall I'm very happy with the structure I have right now, besides that using a service locator makes my IDE confused and breaks all intellisense :roll:.
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

arborint wrote:I don't think either example is MVC (in the pattern, not framework sense), but given the simplicity of the examples that is understandable.
I'm sure both examples are MVC. MVC is just a separation of concerns.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Front/Action Controller and Template solution

Post by Christopher »

Hurreman wrote:Thanks arborint, I'm glad to hear that I've at least managed to follow some best practices. And I suppose it makes sense that controllers and views don't get separated too strictly in a web application. Perhaps I'm not making a good example of MVC, but that's fine with me. My goal is to make my life as a web developer easier by using better and reusable code, and most of all I wanted to make sure that I was heading in the right direction.
You might want to get involved with Skeleton. There are 3-4 of us working on it now. It is so close to what you have that you wouldn't need to change your code much at all. But you would get the benefit of all the other things available. We are always looking for people to get involved.
(#10850)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Front/Action Controller and Template solution

Post by Christopher »

blueyon wrote:I'm sure both examples are MVC. MVC is just a separation of concerns.
MVC is two separations and some dependencies that people generally agree about (but not totally agree about ;)). In my opinion, when you have Controller::render() you are combining the View and Controller. That's not a criticism. I think that is a very reasonable things to do.

I'm not one of those MVC for MVC's sake types. MVC helps solve certain problems cleanly. Implementing a Presentation layer (MP) solves many other problems cleanly. I think (in PHP) you should be able to mix the two within applications as appropriate.
(#10850)
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

arborint wrote:In my opinion, when you have Controller::render() you are combining the View and Controller.
I used to think this aswell. I spent ages trying to come up with composite controllers that would combine the output from templates. The fact is the render method is just a trigger for the View or template engine that is being used.

It could be like this:

Code: Select all

 
<?php
class PageController {
    protected $id;
    protected $template;
    protected $children = array();
    protected $engine   = 'default';
    protected $cache    = FALSE;
    
    function __construct($registry) {
        $this->registry = $registry;
        
        $this->view = new View();
    }
    
    function assign($key, $value) {
        $this->view->set($key, $value);
    }
    
    function render($filename) {
        foreach ($this->childen as $child) {
            $this->view->set($child->getId(), $child->render());
        }
        
        return $this->view->fetch($this->template, $this->engine, $this->cache);
    }
}
?>
 
Remember the controller decides which models to load and which views to render.

You stated in one of your posts that the view might be different objects that can use any method necessary as long as get the job done. I disagree! You can make a composite pattern of controllers

I don't believe the database should be accessed from the view. Sometimes when you need to render small parts of the page a lot of functionality is required including business logic.

For example if you have a shopping cart box on a e-commerce site. You might have want this box to be able to update product quantities and return a ajax response instead of reloading the whole page. The business logic might be:

$model->cart->updateProductQuantity($product_id, $qty);

Do you really want the model to be updating quantities from the view?

The controller and view are a lot more tightly coupled than the model. As you know a lot of frameworks have a render method on the page controller (Zend, Smfony, Akelos, RonR, Solar, etc..). Its not actually mxing things up that much. The controller needs to know somethings about the view because its passing some data into it.

Besides there is no 100% keep every strictly away from each other. If there is a ajax request that requires a small bit of html I normally stick it in the controller.

I think you are wrong to say just because we have the render method in a page controller that our frameworks are not MVC.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: Front/Action Controller and Template solution

Post by Christopher »

I think you would need to find a definition of MVC that did not have a dependency arrow going from the View to the Model before I would agree with your statement that the View should not access the Model. Once you proved me wrong on that point then we could pretty easily identify the rest of my misunderstandings...
(#10850)
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

This is probably not the best one because its from tony marstons web site:

http://www.tonymarston.co.uk/php-mysql/ ... ler-02.png
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

Actually I don't mind if people put the models into the views. It can save time.

When you are using objects as views you are just adding an extra layer. Rename your view objects to controllers. It makes having something thats job is to render a view having model that takes a request and updates a database.

Actually that wasn't the point I was defending having a render method in the page controller.
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: Front/Action Controller and Template solution

Post by Eran »

If you rename your view objects into controllers, why stop there? rename your models into controllers, have just one big giant class that performs everything seamlessly and integrated.

The point of having controllers is to abstract non-view logic pertaining to request / response handling. Controllers control the flow of the application by matching models with views, and also allow for abstracting common setup routines in the flow structure (such as form handling), which are outside of the scope of either the model or the view.
blueyon
Forum Commoner
Posts: 76
Joined: Tue Oct 30, 2007 9:53 am

Re: Front/Action Controller and Template solution

Post by blueyon »

pytrin wrote:If you rename your view objects into controllers, why stop there? rename your models into controllers, have just one big giant class that performs everything seamlessly and integrated.

The point of having controllers is to abstract non-view logic pertaining to request / response handling. Controllers control the flow of the application by matching models with views, and also allow for abstracting common setup routines in the flow structure (such as form handling), which are outside of the scope of either the model or the view.
This is what I have just stated, but arborint is processing form data in his views. Thats why I advised him to rename the some of his views to controllers.
Post Reply