how can I improve my code? (homemade php mvc)

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

Post Reply
old_iron
Forum Newbie
Posts: 7
Joined: Sun Aug 10, 2008 9:12 am

how can I improve my code? (homemade php mvc)

Post by old_iron »

Hello ladies and gentlemen,

I'd like to get some input on how I can best improve my web application programming. During college I played around with writing a framework for myself, and now I've improved it and use it for web applications. It works fairly well at the moment but I know it could be better.

I use my interpretation of the MVC pattern, and use Controllers to populate variable elements of a web page. Each controller calls an Action (a sub-Controller) and this action returns a view, for example an html table of articles fetched from a database. I use a Data Access Object to get the data required. Actions may consist of further sub-Actions so if a certain page element has two sections, each would be created from a sub-Action.

Here is some sample code: (not the exact code but close enough)

Code: Select all

<?php
//this class controls the entire web page
class FrontController {
    function run() {
        //parse request
        $r = new Request();
        //instantiate appropriate action
        $a = new Action($r);
        return $a->run();
 
        //or call multiple Actions for multiple page sections
    }
}
class Action extends Controller {
    function __construct(Request $r) {
        $this->r = $r;
    }
    function run() {
        return $this->execute();
    }
    function execute() {
        $data = DAO::getData($param);   //get some data from the database
        //do something with $data maybe
        return $data->render();
 
        //or call multiple sub-Actions and return the complete composite view from these actions
    }
}
?>
I can see some things wrong with my code already. First, I am using the Controller to directly access the data layer, and also putting business logic in Controller classes (Actions are still Controllers). As I understand it, manipulation of domain objects/data should be done by a model class and not by a controller class.

1. Have I got this right?

Secondly, right now for complex views with multiple variable sections, I am using a seperate class for each action. So if I had an 'articles' module, then the base Action would be ArticlesAction which would parse the request and find that, say, the user wants to see a list of all articles. So this ArticlesAction would call a ShowArticlesAction which would return the rendered data. ArticlesAction may call more than one action, such as load a list of the Top 5 Viewed Articles and show this on every articles page regardless of whether the user is viewing one article, a list of articles, an article search page, whatever. So it might load a ShowArticlesAction and a ShowTopFiveArticles action.

This requires creating module-specific actions (classes) for every action, which may be as trivial as getting a simple article count from the database and displaying it on every article page.

2. Would I be better served with a 'model' class with methods instead of seperate classes for each action? So each 'action' could be a method in the class. Say I'd use an ArticleModel which could be given parameters (which method to run and its parameters) and return an overall, possibly composite, view. This way all module-specific operations would be put in one class and avoid me having to create classes for trivial actions (I am sure running a method in an instantiated class is better performance-wise than instantiating a new class and running one of its methods).

3. Most website operations include fetching or saving information from/to a database or other data source. The way I have things now, I create a class corresponding to an entity created from a database (not necessarily one class per table) and then create Action classes to manipulate those objects, or if 2. is approved, I may add a method to a Model class. I'm not even sure if this is the best way to go about things, the simplest would be to create an Article object and include all the operations in there without the need for a Model class at all.. has anyone done this?

Any ideas would be gratefully appreciated, this is a learning curve for me done for the experience as well as the challenge of programming efficiently.. :)
User avatar
it2051229
Forum Contributor
Posts: 312
Joined: Tue Dec 25, 2007 8:34 pm

Re: how can I improve my code? (homemade php mvc)

Post by it2051229 »

creativity...
old_iron
Forum Newbie
Posts: 7
Joined: Sun Aug 10, 2008 9:12 am

Re: how can I improve my code? (homemade php mvc)

Post by old_iron »

it2051229 wrote:creativity...
huh?
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: how can I improve my code? (homemade php mvc)

Post by alex.barylski »

I don't have much time to disscuss this right now but I"ll come back later and chime in some more...

I just want to say that...I personally agree with your understanding of MVC for the most part. Thing is, most people have varying understandings and what should go where and why, each unique to one's development style/taste and project requirements.

Personally I use a single controller action for an entire view -- complex or not. I'm not sure I understand how multiple controllers could be used for complex views...I have heard others disscuss similar ideas though so your not alone. I'd like to see a more indepth example of how that works in your framework.

What is most important is that you seperate your concerns. Model, View, Controller and you seem to essentially be doing that.

My controllers are really simple. I instantiate the model, get the details and inject that stuff into the view template and send to screen for rendering.

More later...

Cheers :)
old_iron
Forum Newbie
Posts: 7
Joined: Sun Aug 10, 2008 9:12 am

Re: how can I improve my code? (homemade php mvc)

Post by old_iron »

Hockey wrote:...
Thanks for your input so far, I look forward to the rest. :)

When I say I have one controller, I might have some common elements on a webpage such as a sidebar with a status box showing a login form, or giving the user a "You are logged in" message or counting their new private messages or something - this would show up on every page and be handled by a LoginBoxController or something similar.

If the page I loaded was to view a specific article, an ArticleController would show the article body and comments or whatever on the appropriate part of the page, while on another part of the page a LoginBoxController would handle the view for that part.

Plus any 'Article' page which could include a 'show single article' page, a 'search for articles' page, a 'view all articles' page etc may have common elements such as a breadcrumb at the top. So on that one, the ArticleController would use a ShowBreadcrumbController and a (if I wanted to show one article), a ShowSingleArticleController and use their combined views to produce the page.

I hope I explained that correctly, I know it's a lot of controllers and I'm coming round to your way of having one controller with many methods a la:

Code: Select all

 
<?php
class ArticleController {
  function run() {
    $article = $this->getSingleArticle(999);
    $breadcrumb = $this->getBreadCrumb();
    return convertToView($article, $breadcrumb, $x, $y, $z....);
  }
  function getSingleArticle($id) { }
  function getBreadCrumb() { }
}
 
Again, I look forward to the rest of your input. :) I'm a beginner at app design and it's great to hear new ideas and perspectives on things. :)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: how can I improve my code? (homemade php mvc)

Post by alex.barylski »

So how does each controller get coordinated to put the right HTML at the right time? Does your front controller take the input of each controller and inject the compiled HTML into a master template???

How does you chain each controller in the proper sequence to ensure the templates are executed correctly and you don't have your footer in your header, etc???

I have considered this approach many times but personally I have opted for the single controller...Both can be used to reuse code I guess...it just depends on what you prefer I guess.

For instance, my application has a paginated list of items with a "pager" widget. I have to initialize that pager widget in each controller that generates a list of any kind. I suppose if I used a multi-controller approach like you I could avoid that duplication but I fear complex forwarding would result in difficult to follow code with out some third party config file which also acted as clear documentation. Also It's easy enough to wrap that duplicated code into a helper object of sorts and just instantiate the object with data from the model and voila, code reuse.

I'm sure it was here where I have followed disscussions about mutiple controllers being used to generate complex views but of course I cannot find any of those topics. :P

I'd like to hear how others maybe used a similar approach to solve the problem of complex views.

You example of a login form, etc...is unique for me. I have seen countless web sites built that way but I never used that approach because I focus mostly on applications where a login form is shown *always* until you login. That effectively swayed my design choices to favour a single controller approach -- although occassionally forwarding does occur but never more than one level keeping indirection to a minimum.

I did implement a wizard once where controller branching was dictated by conditional statements and I have to admit...it was a bad design choice...all my code was easy to understand except the wizard...it was confusing to keep track of which controller was used when and why.
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: how can I improve my code? (homemade php mvc)

Post by Christopher »

Urg ... MVC discussions. ;) I think a place to start is the fact that you have a Page Controller that is mis-named as 'FrontController'.
(#10850)
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: how can I improve my code? (homemade php mvc)

Post by alex.barylski »

Urg ... MVC discussions
Thats what I was thinking but then again it never hurts to hear other perspectives...
I think a place to start is the fact that you have a Page Controller that is mis-named as 'FrontController'.
Like this for instance...although my front is a little more elaborate...it's not much more (no advanced router abstractions, etc). My front controller essentially takes a request in a fixed format and instantiates a action controller.

What would he/she have to add or retract to their interpretation of a front controller in order to make it acceptable to you, in that you would agree it's a front and not page controller.
old_iron
Forum Newbie
Posts: 7
Joined: Sun Aug 10, 2008 9:12 am

Re: how can I improve my code? (homemade php mvc)

Post by old_iron »

Hockey wrote:So how does each controller get coordinated to put the right HTML at the right time? Does your front controller take the input of each controller and inject the compiled HTML into a master template???

How does you chain each controller in the proper sequence to ensure the templates are executed correctly and you don't have your footer in your header, etc???
My FrontController (probably should be called an ApplicationController) has a method which puts the results (view) of various sub-controllers into page elements. Each sub-controller has an id which is used to populate the appropriate part of the template. The order in which the controllers are executed and their views captured isn't important this way, although in some cases yes, you might want some information from a previous controller to be available to a subsequent controller.
You example of a login form, etc...is unique for me. I have seen countless web sites built that way but I never used that approach because I focus mostly on applications where a login form is shown *always* until you login. That effectively swayed my design choices to favour a single controller approach -- although occassionally forwarding does occur but never more than one level keeping indirection to a minimum.
I might just be being dense here, but if you've got a login box like that, or even something as simple as a dynamically-generated date, plus the main 'dynamic' content of a page (such as a list of results or an article view or whatever) what are your options? You either have to put the dynamic elements in the template directly plus the 'variable' dynamic content as the main body or whatever, or you assign each dynamic element a controller and do it in a class, and populate the template that way. Essentially it's the same thing but if some page elements have complex logic (as well as accessing the underlying model etc) would you put them in a template?

I guess you could make all controllers extend a base controller class which would run actions to capture the view of each dynamic element of a page like:

class BaseController {

Code: Select all

function execute() {
  $t = new Template();
  $t->set('Header', $this->getHeader());
  $t->set('Body', $this->getSubController()->execute());
  $t->set('LoginBox', $this->getLoginBox());
  $t->set('Footer', $this->getFooter());
}
 
}
The base controller would know how every page in the website is displayed (with a date, loginbox, dynamic menu etc..) and then it could set the main content area (a div or whatever) with the result of the controller/action invoked by the request.

Honestly, I'm not sure if I'm making this more complicated than they should be.. how would you handle this? :)

Arborint, thanks for the input - I admit I get confused by what Controller is which. It should be a Page Controller to run the specific action, but would a PageController instantiate the session, request, registry etc as well? Shouldn't that go in a front controller?
old_iron
Forum Newbie
Posts: 7
Joined: Sun Aug 10, 2008 9:12 am

Re: how can I improve my code? (homemade php mvc)

Post by old_iron »

Hockey wrote:
Urg ... MVC discussions
Thats what I was thinking but then again it never hurts to hear other perspectives...

What would he/she have to add or retract to their interpretation of a front controller in order to make it acceptable to you, in that you would agree it's a front and not page controller.
'He'. :)

As for other peoples perspectives, that's why I posted, to get some ideas.. I realise that this sort of thing was a novelty a few years ago and now it's just another subject done to death with a million interpretations pointing the finger at each other for being 'wrong', but I'm a novice and I'd like to learn more.. I don't know how else to do so without asking people who've been there and done that. :)
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Re: how can I improve my code? (homemade php mvc)

Post by Christopher »

Code: Select all

class PageController {
    function run() {
        $r = new Request();
        include 'controllers/Action.php';
        $a = new Action($r);
        return $a->run();
    }
}

Code: Select all

class FrontController {
    function run() {
        $r = new Request();
        $action = isset($r->action) ? $r->action : 'default';
        $filename = "controllers/$action.php";
        if (file_exists($filename)) {
            include $filename;
            $a = new $action($r);
            return $a->run();
        }
    }
}
(#10850)
Post Reply