SitePoint Sponsor

User Tag List

Page 1 of 4 1234 LastLast
Results 1 to 25 of 83
  1. #1
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Simple MVC Example

    I have just done a quick MVC example. It took me about 20 minutes to write.

    Its a little to big to post the code on the forum so I have added it as an attachment.

    Please let me know what you think!
    Attached Files Attached Files
    Last edited by blueyon; Jun 26, 2007 at 07:05.

  2. #2
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    Please let me know what you think!
    Uhm, although we obviously have different opinions on how a View and the parsing of it works, I quite like it. It's a darn shame this is in php4, instead of php5 though, you might wish to reconsider that? Also, as I think this is for people new to the subject, I would choose to actually implement at least one model and one view. For people without any MVC experience, it's often unclear where responsibilities lie.

    Wait, for those who are experienced in MVC, it's still unclear where responsibilities lie.

  3. #3
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I think what I have done is correct. It uses the same sort of MVC style as codeignitor, but not using the loader class.
    Last edited by blueyon; Jun 27, 2007 at 06:22.

  4. #4
    SitePoint Zealot Rotwang's Avatar
    Join Date
    Jun 2005
    Posts
    104
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You need a "var $locator;" at the top of your controller.php

  5. #5
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hey blueyon

    Thanks for the great example it's really nice and clear for an MVC beginner such as myself especially for some of the library objects

    So, would I incorporate multiple views and models in each controller?

    IE what if the home controller included news artcles, events aswell as main content.

    Would it be a bit cheeky to ask for an example with the view(s) and model(s) incorporated

  6. #6
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    would it be something like this

    PHP Code:
    class ControllerHome extends controller {
        function 
    ControllerHome(&$locator) {
            
    $this->view =& $locator->get('view');
            
    $this->model =& $locator->get('model');
            
    $this->response =& $locator->get('response');
        }
        
        function 
    index() {
            
    $news_model $this->model->get('news');
            
    $events_model $this->model->get('events');

            
    $articles   $news_model->get_articles();
            
    $events     $events_model->get_events();

            
    $content     $this->view->fetch('home');
            
    $news_view   $this->view->set($articles);
            
    $events_view $this->view->set($events);
            
    $template    $this->view->set($content,$news_view->fetch('news'),$events_view->fetch('events');
            
    $this->response->set($template->fetch());
        }


  7. #7
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could... However you are going to be faced with a nightmare in regards to maintainance and for future growth; What happens when one part changes? You should be able to do those changes, without effecting the others.

    So, you are looking for Composite, where you separate each component into it's own Controller, ie

    Code:
    + Home Controller
    + --- News Controller
    + --- Polls Controller
    + --- Etc...
    Here is some script off the top of my head,

    PHP Code:
    class Composite {
    protected 
    $children = array();

    public function( 
    $id false ) {
    if( 
    $id ) {
    $this -> id $id;
    }
    }

    public function 
    getId() {
    return 
    $this -> id;
    }

    public function 
    getChildren() {
    return 
    $this -> children;
    }

    public function 
    hasChildren() {
    return 
    count$this -> children );
    }

    public function 
    attachComposite $composite ) {
    $this -> children[$composite -> getId()] = $composite;
    }

    So you can do this,

    PHP Code:
    $home = new Home_Controller'home' );
    $home -> attach( new News_Controller'news' ) );
    $home -> attach$polls = new Polls_Controller'polls' ) );
    // ... etc 
    It also means, that you can attach further children, to what is a child already...

    PHP Code:
    // ...
    $polls -> attach( new Another_Child_Controller'...' ) );
    // and so on 
    Once you have your structure, you need to recurse over it; For me, each Composite is in it's self a Controller, so the recursion looks like this,

    PHP Code:
    // ...
    public function beginComposite $composite ) {
    ob_start();
    $this -> traverse$composite );
    echo 
    ob_get_clean();
    }

    public function 
    traverseComposite $composite ) {
    $children $composite -> getChildren();
    foreach( 
    $children as $child ) {
    ob_start();
    $this -> traverse$child );
    $context -> set$child -> getId(), ob_get_clean() );
    // job done 
    The $context is a container I have, which I pass in the class methods (not shown) which is the content generated by the Views. You would need to understand how the recursion works, to better understand the underlying approach how the container plays its part in how the Home View is put together

  8. #8
    Put your best practices away. The New Guy's Avatar
    Join Date
    Sep 2002
    Location
    Canada
    Posts
    2,087
    Mentioned
    1 Post(s)
    Tagged
    1 Thread(s)
    If your just refactoring configuration just use inheritance instead of composites.
    "A nerd who gets contacts
    and a trendy hair cut is still a nerd"

    - Stephen Colbert on Apple Users

  9. #9
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'm going to try an update with what Dr Livingston has said here and what kyberfabrikken has said in this post.

  10. #10
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Cheers for the response guys, certainly makes more sense Dr Livingston I'll have to have a play around, I'd be very interested to see your response blueyon

    Thanks again

    Crabby

  11. #11
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The only way I can think of to get this to work without messing up the controller or the modules is for the base controller to extend the composite.

    Is this correct?

  12. #12
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have not got a clue how to implement the composite pattern with a controller, module loader class and template.

    I can implement a composite view, but I'm not sure thats what Dr Livingston means.

  13. #13
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Dr Livingston are you shure you have this right?

    Your implementing composite controllers. The are plenty of composite view examples, but I can not find any for composite controllers.

  14. #14
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You can implement the Composite as you see fit, it doesn't really have to be implemented from the View layer in particular yes?

    I implement the Composite in a number of ways, so you are not really restricted to the View [MVC] alone; Some people implement their Views as Composites, using one controller for example...

    But that is but one implementation, and it's not written in stone that you need to follow that particular implementation. So the pattern Composite is exactly the same as that of the Composite View. There is no difference, so it's down to your own implementation of how you manipulate an hierarchacal structure.

    Hope this helps?

  15. #15
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    The are plenty of composite view examples, but I can not find any for composite controllers.
    WACT does it.
    Zealotry is contingent upon 100 posts and addiction 200?

  16. #16
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by auricle View Post
    WACT does it.
    I have just looked at wact and yes it does have this feature.

    What I'm thinking of is a module manager that feeds the generated html back to the main controller and is set to the template.

    You should have the ability on some web applications to install / uninstall modules.

    If there is no module manager then you need to do a lot of repeative coding on each controller to load the module and attach it to the main controller.

  17. #17
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Assuming that most of these 'modules' (however you define them) will have some output in the page (composite view), then you could write a module manager that fits into the front controller (same layout for every page) or the page controller that is selected by the front controller (different layouts for different kinds of pages). Then, I suppose, you only have to do repetitive coding for each module whose output makes up the page.

    I can see this approach working well within WACT.
    Zealotry is contingent upon 100 posts and addiction 200?

  18. #18
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by auricle View Post
    Assuming that most of these 'modules' (however you define them) will have some output in the page (composite view), then you could write a module manager that fits into the front controller (same layout for every page) or the page controller that is selected by the front controller (different layouts for different kinds of pages). Then, I suppose, you only have to do repetitive coding for each module whose output makes up the page.

    I can see this approach working well within WACT.

    The different components that make up a page on my applications goes like this:

    Code:
    + layout
    +-- content
    +-- header
    +-- footer
    +-- box1
    +-- box2 etc..
    I don't want modules loading on every page because some might not require them such as when using ajax.

  19. #19
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by blueyon View Post
    I don't want modules loading on every page because some might not require them such as when using ajax.
    In that case, you wouldn't configure the layout in the front controller.

    Don't understand the bit about ajax!
    Zealotry is contingent upon 100 posts and addiction 200?

  20. #20
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have just updated the example using Konstrukt's Assembler from another post and added a module loader class.

    I'm still having trouble implemeting the composite pattern with my controller.

    If there is any one who can given an example with the code I have done showing how to implement the composite pattern with my controller it would be great!
    Attached Files Attached Files

  21. #21
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ah good stuff blueyon need to check this out

  22. #22
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > If there is any one who can given an example with the code I have done showing how to
    > implement the composite pattern with my controller it would be great

    I'll download your file now and take a look later

    > I don't want modules loading on every page because some might not require them such
    > as when using ajax.

    As you recurse over your structure, it's just a case of pulling a given Composite out, prior to execution thus it's ignored altogether. This is what you want, since you can have a base layout structure generated for you on each request, rather than have a different layout for each request.

    In this case, you don't really need any sort of configuration, other than how your recursion would know which Composite to pull out.

  23. #23
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I decided to posting the code might help.

    How would you make this a composite controller?

    My framework sort of follows the style from an example given on phpit.com.

    PHP Code:
    <?php
    // Controller
    class Controller {
        function 
    __construct(&$locator) {
            
    $this->locator =& $locator;
        }
    }

    // Module
    class Module {
        var 
    $data = array();
        
        function 
    __construct(&$locator) {
            foreach (
    glob(DIR_MODULE '*.php') as $file) {
                include(
    $file);
                
                
    $class 'Module' basename($file'.php');
                
                
    $this->data[basename($file'.php')] = new $class(&$locator);
            }
        }
        
        function 
    fetch() {
            
    $module_data = array();
            
            foreach (
    array_keys($this->data) as $key) {
                
    $module_data[$key] = $this->data[$key]->fetch();
            }
            
            return 
    $module_data;
        }
    }

    // Controller Home
    class ControllerHome extends Controller {
        function 
    index() {
            
    $view1 =& $this->locator->get('view');
            
            
    $view1->set('title''Simple MVC');
            
            
    $view2 $this->locator->createView();
            
            
    $url =& $this->locator->get('url');
            
            
    $view2->set('home'$url->href('home'));
                    
            
    $view1->set('content'$view2->fetch('content/home.tpl'));
            
            
    $module =& $this->locator->get('module');
            
            
    $view1->set($module->fetch());
            
            
    $response =& $this->locator->get('response');
            
            
    $response->set($view1->fetch('layout.tpl'));
        }
    }

    // Module Box1
    class ModuleBox1 extends Controller {
        var 
    $id 'box1';
        
        function 
    fetch() {
            return 
    'This is box 1';
        }
    }
    ?>

  24. #24
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    // Controller Home

    class ControllerHome extends Controller { ... 
    You couldn't make that a Composite controller in particular, but you would need to encapsulate what you are doing here, in this class method, into a separate controller; I refer to this as an Action Handler myself.

    Your Controller I refer to it being a Application_Action_Controller, akin to Zend Framework (but differing implementations). But it depends really, on how involved you want to get?

    By that I mean, you could have a Composite based Controller structure, but do you need that level of refinement... You could just as well manage easily enough with just a Composite structure on your View instead, going by your posted example (found in download) in my view.

    At the end of the day, it really depends on the complexity of your Page structure. If you've got a tonne of separate individual components your page is comprised of, then go the Controller route, otherwise take the View route; Take the wrong route and your going to give yourself more work to do.

    PHP Code:
    interface QComposite_Interface {
            public function 
    getId();
            public function 
    getChildren();
            public function 
    hasChildren();
            public function 
    attachQComposite_Interface $composite );
        }

    abstract class 
    QComposite implements QComposite_Interface {
            protected 
    $children = array();
            protected 
    $id;
            
            public function 
    __construct() {}
            public function 
    getId() {
                return 
    $this -> id;
            }
            
            public function 
    getChildren() {
                return 
    $this -> children;
            }
            
            public function 
    hasChildren() {
                return 
    count$this -> children );
            }
            
            public function 
    attachQComposite_Interface $composite ) {
                
    $this -> children[$composite -> getId()] = $composite;
            }
        }

    interface 
    QAction_Handler_Interface extends QComposite_Interface {}

    abstract class 
    QAction_Handler implements QAction_Handler_Interface {
            protected 
    $children = array();
            protected 
    $id;
            
            public function 
    __construct() {}
            public function 
    getId() {
                return 
    $this -> id;
            }
            
            public function 
    hasChildren() {
                return 
    count$this -> children );
            }
            
            public function 
    getChildren() {
                return 
    $this -> children;
            }
            
            public function 
    attachQComposite_Interface $composite ) {
                
    $this -> children[$composite -> getId()] = $composite;
            }
            
            abstract public function 
    executeQDataspace_Interface $context );
        } 
    Then I use the following, to build my Controller structure,

    PHP Code:
    abstract class QAction_Handler_Factory {
            protected 
    $children = array();
            
            public function 
    __construct$children ) {
                
    $this -> children $children;
            }
            
            public function 
    get() {
                
    $args func_get_args();
                
    $parent array_shift$args );
                
    $composite $this -> create();
                if( 
    $parent instanceof QAction_Handler_Interface ) {
                    
    $parent -> attach$composite );
                }
                
                foreach( 
    $this -> children as $child ) {
                    
    $classname $this -> formatName$child );
                    
    $instance = new $classname();
                    
    $instance -> get$composite );
                }
                
                return 
    $composite;
            }
            
            protected function 
    formatName$name ) {
                return 
    'Q'.ucwords$name ).'_Factory';
            }
            
            abstract protected function 
    create();
        } 
    The concrete implementation of the factories are these for example,

    PHP Code:
    final class QPage_Factory extends QAction_Handler_Factory {
            public function 
    __construct() {
                
    parent::__construct( array( 'head''body''menu' ) );
            }

            protected function 
    create() {
                return new 
    QPage_Action_Handler();
            }
        }
        
        final class 
    QHead_Factory extends QAction_Handler_Factory {
            public function 
    __construct() {
                
    parent::__construct( array() );
            }

            protected function 
    create() {
                return new 
    QHead_Action_Handler();
            }
        }
        
        final class 
    QBody_Factory extends QAction_Handler_Factory {
            public function 
    __construct() {
                
    parent::__construct( array( 'search' ) );
            }

            protected function 
    create() {
                return new 
    QBody_Action_Handler();
            }
        }
        
        final class 
    QMenu_Factory extends QAction_Handler_Factory {
            public function 
    __construct() {
                
    parent::__construct( array() );
            }

            protected function 
    create() {
                return new 
    QMenu_Action_Handler();
            }
        }
        
        final class 
    QSearch_Factory extends QAction_Handler_Factory {
            public function 
    __construct() {
                
    parent::__construct( array() );
            }

            protected function 
    create() {
                return new 
    QSearch_Action_Handler();
            }
        } 
    PHP Code:
    final class QPage_Action_Handler extends QAction_Handler {
            public function 
    __construct() {
                
    $this -> id 'page';
            }
            
            public function 
    executeQDataspace_Interface $context ) { // script goes here }
        
    }

    final class 
    QHead_Action_Handler ... etc ... 
    Now... Where I talked about pulling out a specific Composite, or for that matter, putting one in, I would do this within the *::create() function it's self, based on a number of rules for that given Composite in question.

    Hope this gives you some enlightment
    Last edited by Dr Livingston; Jul 18, 2007 at 11:56.

  25. #25
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the reply Dr Livingston, just need to get my head around it

    Blueyon, are modules seperate elements of the page IE header, Navigation, News Artcles etc?
    Last edited by crabby80; Jul 19, 2007 at 06:08.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •