SitePoint Sponsor

User Tag List

Page 1 of 3 123 LastLast
Results 1 to 25 of 83

Hybrid View

  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 06: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 05: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
    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?

  14. #14
    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?

  15. #15
    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.

  16. #16
    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?

  17. #17
    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

  18. #18
    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

  19. #19
    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.

  20. #20
    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';
        }
    }
    ?>

  21. #21
    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 10:56.

  22. #22
    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 05:08.

  23. #23
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by crabby80 View Post
    Thanks for the reply Dr Livingston, just need to get my head around it

    Blueyon, are modules seperate elements of the page IE header, news artcles etc?
    From what I understand modules are small pieces of HTML that make up parts of the a page and can have some functionality.

    I normally have a header, footer and then have boxes down the sides.

    Just did a quick update adding mail and session classes to the library.
    Attached Files Attached Files
    Last edited by blueyon; Jul 19, 2007 at 06:20.

  24. #24
    SitePoint Addict crabby80's Avatar
    Join Date
    May 2007
    Posts
    387
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Blueyon

    I'm a bit of a noob with MVC so sorry about all these questions, It's just I find your example nice and easy to understand..............well "easier"

    I'm trying to incorporate a latest news module, but I seem to be having trouble with the model part, would it be something like the following???

    PHP Code:
    class ModuleNews extends Controller {
        function 
    fetch() {
            
    $model $this->locator->createModel('news');
            
    $articles $model->latest_news();
            
    $view $this->locator->get('view');
                    
    $view->set('articles',$articles;)
            return 
    $view->fetch('module/news.tpl');*/
        }
    }

    class 
    ModelNews extends Model {
        function 
    __construct($locator) {
            
    $this->locator $locator;
        }
        
        function 
    latest() {
             return 
    $this->getRows("SELECT * FROM news");
        }

    Do you have a simple example??

  25. #25
    SitePoint Addict
    Join Date
    Feb 2006
    Posts
    281
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I might have got have got some points worng on the model.

    You could do it like this:

    PHP Code:
    class ModuleNews extends Controller {
        function 
    fetch() {
            
    $view $this->locator->get('view');
            
            
    $model_news $this->locator->createModel('news');
            
            
    $view->set('articles'$model_news->getLatest());
            
            return 
    $view->fetch('module/news.tpl');
        }
    }

    class 
    ModelNews extends Model {
        function 
    getLatest() {
            return 
    $this->getRows("SELECT * FROM news");
        }

    if you add a constructor in the extended model you need to re-add:

    $this->database =& $locator->get('database');


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
  •