SitePoint Sponsor

User Tag List

Page 3 of 5 FirstFirst 12345 LastLast
Results 51 to 75 of 120
  1. #51
    public static void brain Gybbyl's Avatar
    Join Date
    Jun 2002
    Location
    Montana, USA
    Posts
    647
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There are several J2EE frameworks that come into mind when talking about single and multiple access points -- for example, the Jakarta Struts project (which uses the MVC Model 2 architecture) uses a single access point, but they kind of blur the line between their front- and page-controllers.

    Turbine uses multiple access points, all of which could potentially forward you through the main access point, if that is the desire of the developer or application designer.

    It's mainly a matter of personal preference.
    Ryan

  2. #52
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I had multiple access points, then it would allow me to have different pages like index.php, products.php, links.php etc. where each page has its own FC (like ProductFrontController LinksFrontController etc.)
    This is the route I took originally, and it works well

    On your other point though, what I've now done is to use some of the example script posted here, and glue that to the front of everything ?

    So I have the Front Controller and Intercepting Filters as one (index.php) which then INCLUDEs the required alternate file, ie Products yes ?

    This Products file, it's self has a Front Controller, ala SWITCH to decide which Page Controller to dispatch (note I use dispatch, and not execute)

    Nothing too bad with this approach surely ? One filter takes care of a log in process, and the alternate Front Controller(s) each look after authentication of an action, ie AddProduct, etc etc

    Comments anyone ?

  3. #53
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Out of curiosity, I notice you have two arguments in your processRequest function. The request var is pretty self -explanatory, but what type of information is usually passed in the $response argument?
    The response contains some methods to send out headers, add cookies, etc. It's not really that important.

    What if HTTPRequest and\or HTTPResponse are not needed for a specific request (can't think of an example right now...): I have then created an HTTPRequest (and\or HTTPResponse) Object that is not going to be used.
    Well, that's the thing with abstraction: if there are some requests that do need a HTTPRequest object and others that don't, you have to choose for the ones that do need it. The HTTPRequest is almost always needed anyway, because it provides access to GET, POST and SERVER, etc. But if you think this is just overhead for your application, you can of course just use GET, POST and SERVER directly, nothing wrong with that.

    I am thinking to change the HTTPRequest and HTTPResponse to Singletons and not passing them around.
    Then you would essentially be making them global variables and possibly breaking layering by allowing any layer to access them, including layers that should remain independent of the request. By not making the objects singletons you force yourself to layer your application.

    In this event, I am thinking about just redirecting to required page as is ? Is that not simpler ?
    The authentication page controller is responsible for a page that displays a form asking for a username and password. That form needs to be validated and depending on whether the username & password are valid, a view needs to be chosen. You soon find yourself with code that looks a lot like the page controller for adding a user. I therefore think it makes sense to make this code a page controller as well.

    I applaud your effort here to make things clear and simple, but I still think that you are blurring the definition of the page controller pattern by mixing the page controller and the front controller patterns together. Someone coming here wanting to understand the page controller pattern might be confused by how you are using the pattern. I propose that you name your new pattern something different than page controller to distinguish it from a true page controller pattern (as Fowler and others intended).
    I agree with you. The example code I provided is not a strict implementation of the pattern, it is a variation of it. However, Mojavi is not a true implementation of the FrontController pattern either, yet it claims to be (I'd be happy to explain the reasons for saying this)

    If you take a look at how Fowler defines the PageController here, there is nothing saying that there cannot be any other code responsible for choosing a PageController based on what the URL is, or that things like InterceptingFilters are not allowed.

    Because of that, and also the fact that I think that the name PageController is the most descriptive of the task of the classes I provided, I don't really see a reason to change the name. I'd also like to mention that in my framework, FrontController is named EntryPoint, but what's in a name eh..

    I personally loved your MVC implementation. Very very simple and to the point. Put a lot of things into perspective, and DID clear up some minor confusions that I had about the "pattern."
    That was the intention of my post: to provide an example of how all the patterns that are discussed about so much can be implemented together (note: can, not must).

    http://www.japha.net/images/MVC.png
    Well, the User*PageControllers do not extend from a base UserController. Also, the formHasBeenSubmitted and formIsValid variables are not defined in that UserController. In the example I provided them simply to illustrate how the control flow looks like. The actual implementation of how forms are validated is left to the developer's creativity, since it is not directly part of the MVC pattern.

  4. #54
    public static void brain Gybbyl's Avatar
    Join Date
    Jun 2002
    Location
    Montana, USA
    Posts
    647
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, the User*PageControllers do not extend from a base UserController. Also, the formHasBeenSubmitted and formIsValid variables are not defined in that UserController. In the example I provided them simply to illustrate how the control flow looks like. The actual implementation of how forms are validated is left to the developer's creativity, since it is not directly part of the MVC pattern.
    Ah. One other thing I was confused about is the implementation of the data model. Where does that fit in? And should the model be readily available to both the view AND the controller? Many of the docs I've read seem to hint that either of the other two layers should be able to access the model.

    What kind of classes would you define (and where would you define them, in terms of the hierarchy) for your data model?
    Ryan

  5. #55
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was inspired by this thread and am now a FrontController believer. I've been kind of against them for a while, but I'm starting to see how they could make life easier, coupled with filtering. Thanks to all who have put in the time to help explain and educate! I've made a couple of files that put the whole thing together and zipped it up. You can get my 'interpretation' of the whole thing here:

    <snip/>

    Actually, it's all of the ideas that have been presented here, but a few little changes. There is a FrontController, PageController, InterceptingFilter and a FilterManager. Everything is run by the FilterManager. Have a look and let me know what you think or if you see room for improvement (which of course you will). Private message me if you want!

    Matt
    Last edited by Mittineague; Dec 18, 2010 at 00:06. Reason: pre-new-sticky cleanup

  6. #56
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    why this :
    PHP Code:
        function addFilter($file) {
            
    $this->filters[] = $file;
        }
        
        function 
    addFilterObject(& $filter) {
            
    $this->filters[] =& $filter;
        } 
    When this would do the same job, and be more intuitive (apart from saving a few lines of code) :
    PHP Code:
        /**
           * @param mixed $f Instance of InterceptingFilter, or filename of the filter to invoke.
           */
        
    function addFilter(&$f) {
            
    $this->filters[] =& $f;
        } 

  7. #57
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You guys are forgetting here that if you run your filters sequentially, by adding them to an array, they lose the ability to actually intercept the request and prevent it from being passed on to the next filter.

    You will have to check a return code or something like that, in short: a less elegant solution IMHO

  8. #58
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    class FrontController /* implements InterceptingFilter */ 
    Oh no!

  9. #59
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Captain Proton
    You will have to check a return code or something like that, in short: a less elegant solution IMHO
    PHP Code:
    class InterceptingFilter
    {
        function 
    execute()
        {
            return 
    true;
        }
    }

    class 
    DummyFilter extends InterceptingFilter
    {
        function 
    DummyFilter($test)
        {
            
    $this->test $test;
        }

        function 
    execute()
        {
            echo 
    "Test : " $this->test "<br>";
            return 
    $this->test != 2;
        }
    }

    // add up some filters
    $GLOBALS['intercepting_filters'][] = new DummyFilter(1);
    $GLOBALS['intercepting_filters'][] = new DummyFilter(2);
    $GLOBALS['intercepting_filters'][] = new DummyFilter(3);

    // run them through
    foreach ($GLOBALS['intercepting_filters'] as $f) {
        if (!
    $f->execute()) break;

    That's not too bad, is it ?

  10. #60
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    why this :
    PHP Code:
        function addFilter($file) {
            
    $this->filters[] = $file;
        }
        
        function 
    addFilterObject(& $filter) {
            
    $this->filters[] =& $filter;
        } 
    When this would do the same job, and be more intuitive (apart from saving a few lines of code) :
    PHP Code:
        /**
           * @param mixed $f Instance of InterceptingFilter, or filename of the filter to invoke.
           */
        
    function addFilter(&$f) {
            
    $this->filters[] =& $f;
        } 

    The only reason I did that is so you can pass a string for the path of the filter class file, and not have to worry about references. But I think I'll change that to just one method. It is more intuitive.

    Matt

  11. #61
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    PHP Code:
    class FrontController /* implements InterceptingFilter */ 
    Oh no!
    Ha ha. I know, but it IS being used as a filter. Even in the first example posted in this thread about intercepting filters, the Front Controller was implementing the interface of the intercepting filter no? How else could it happen?

    Matt

  12. #62
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How else could it happen?
    I suppose, like this :
    PHP Code:
    class FrontController {
        var 
    $filterManager;
        function 
    FrontController() {
            
    $this->filterManager =& new FilterManager();
        }

        function 
    serve()
        {
            
    // run filters
            
    $this->filterManager->execute();
            
    // select pagecontroller
            
    $page $this->getPageName();
            
    // run pagecontroller
            
    $this->executePageController($page);
        }

        function 
    executePageController($page)
        {
            if( 
    $class $this->includePageController() ) {
                
    $pageController =& new $class();
                
    $pageController->execute();
            }
        }

    As far as i interpret it : The FrontController is the main entrypoint for your application (hence front). Normally you enter php by the execution of the script index.php. If you weren't using OO-syntax at all, you could say that index.php is your frontcontroller. To translate this procedural implementation into the OO-world, you could make a class called FrontController that does the exact same thing as index.php. So to keep it clean, you shouldn't do anything in index.php except include, instanciate and execute the class FrontController.

  13. #63
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    I suppose, like this :
    PHP Code:
    class FrontController {
        var 
    $filterManager;
        function 
    FrontController() {
            
    $this->filterManager =& new FilterManager();
        }

        function 
    serve()
        {
            
    // run filters
            
    $this->filterManager->execute();
            
    // select pagecontroller
            
    $page $this->getPageName();
            
    // run pagecontroller
            
    $this->executePageController($page);
        }

        function 
    executePageController($page)
        {
            if( 
    $class $this->includePageController() ) {
                
    $pageController =& new $class();
                
    $pageController->execute();
            }
        }

    As far as i interpret it : The FrontController is the main entrypoint for your application (hence front). Normally you enter php by the execution of the script index.php. If you weren't using OO-syntax at all, you could say that index.php is your frontcontroller. To translate this procedural implementation into the OO-world, you could make a class called FrontController that does the exact same thing as index.php. So to keep it clean, you shouldn't do anything in index.php except include, instanciate and execute the class FrontController.
    Yeah OK. I see what you mean. The only thing here that *isn't* happening now is that there aren't post filters being executed AFTER the page controller is being executed. Wouldn't that be the prefered method? Thanks for your feedback. Much appreciated.

    M

  14. #64
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    See your point, though you don't actually need them in my view ?

    For each filter, you can do something before a filter is executed, and also after a filter is executed ?

    In the example the good Captain posted, wasn't the Front Controller executed (treated) like a filter as well, from what I can tell ?

    This being the case, then if you need post processing after the Front Controller, this can be done easily

    I put together the script posted on this thread, and ran a few pre and post echos on each filter class, including the Front Controller, and everyone came up roses so to speak

    Or have I missed something ?

  15. #65
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    For each filter, you can do something before a filter is executed, and also after a filter is executed ?
    Ok, i see the point, but i still must oppose to letting the FrontController extend InterceptingFilter. It just doesn't make sense.

  16. #66
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by kyberfabrikken
    Ok, i see the point, but i still must oppose to letting the FrontController extend InterceptingFilter. It just doesn't make sense.
    The Front Controller is not extending, only implementing an interface that the filter manager can use. After giving it some thought... The front controller in this case (being used as a filter) still is the entry point . It's handling the request and providing an action based on that request, regardless of whether or not it's in the filter chain.

    If the FrontController was NOT a filter, the FilterManager could do a check, and if the last filter has been executed, the FrontController could execute the page, and the return to the filter chain, handling post filtering...
    Last edited by mwmitchell; Jan 21, 2007 at 06:39.

  17. #67
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mwmitchell
    The Front Controller is not extending, only implementing (...)
    Ok yes, that makes it a bit better, but still ...

    Quote Originally Posted by mwmitchell
    If the FrontController was NOT a filter, the FilterManager could do a check, and if the last filter has been executed, the FrontController could execute the page, and the return to the filter chain, handling post filtering...
    I thought about it, and even though this doesn't change a thing, i like that construction better.
    What about this approach then :
    PHP Code:
    class Executeable
    {
        function 
    execute()
        {
        }
    }

    class 
    FilterManager
    {
        var 
    $controller=null;
        var 
    $filterChain=array();
        var 
    $pointer=0;

        function 
    FilterManager(&$controller)
        {
            
    $this->controller =& $controller;
        }

        function 
    addFilter(&$f)
        {
            
    $f->attachFilterManager($this);
            
    $this->filterChain[] =& $f;
        }

        function 
    execute()
        {
            
    $this->pointer 0;
            
    $this->executeNext();
        }

        function 
    executeNext()
        {
            if (
    $this->pointer count($this->filterChain)) {
                
    $next =& $this->filterChain[$this->pointer++];
            } else {
                
    $next =& $this->controller;
            }
            if (
    $next !== null) {
                
    $next->execute();
            }
        }
    }

    class 
    InterceptingFilter /* implements Executeable */
    {
        var 
    $filterManager;

        function 
    attachFilterManager(&$filterManager)
        {
            
    $this->filterManager =& $filterManager;
        }

        function 
    execute()
        {
            
    // pre-processing here
            
    $this->executeNext();
            
    // post-processing here
        
    }

        function 
    executeNext()
        {
            
    $this->filterManager->executeNext();
        }
    }

    class 
    DummyFilter extends InterceptingFilter
    {
        function 
    DummyFilter($test)
        {
            
    $this->test $test;
        }

        function 
    execute()
        {
            echo 
    "Filter : " $this->test " : begin<br/>";
            if (
    $this->test != 2) {
                
    $this->executeNext();
            }
            echo 
    "Filter : " $this->test " : end<br/>";
        }
    }

    class 
    FrontController /* implements Executeable */
    {
        var 
    $filterManager;

        function 
    FrontController()
        {
            
    $this->filterManager =& new FilterManager($this);

            
    // add up some filters
            
    $this->filterManager->addFilter(new DummyFilter(1));
    //        $this->filterManager->addFilter(new DummyFilter(2));    // this one breaks the chain
            
    $this->filterManager->addFilter(new DummyFilter(3));
        }

        function 
    processRequest()
        {
            
    $this->filterManager->execute();
        }

        function 
    execute()
        {
            echo 
    "<p>Frontcontroller here. Normally the execution would be handed over to a pagecontroller at this point</p>";
        }
    }
    $fc =& new FrontController();
    $fc->processRequest(); 

  18. #68
    SitePoint Guru
    Join Date
    Oct 2001
    Posts
    656
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Executable is named RequestProcessor in my code. The FrontController is not an InterceptingFilter. InterceptingFilter and FrontController do share the RequestProcessor interface, though.

  19. #69
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Right, so we eventually ended up with more or less the same thing, i take it ? But that's a good thing, since it implies that it's not just within our own minds that it makes sense.

    I like the name RequestProcessor better than Executeable, by the way.

    As a sidenote ; Couldn't FilterManager above be considered a fine example of the Decorator pattern ?

  20. #70
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by AlexBrina
    Hey man, this thread seems like a Frankenstein tutorial of patterns isn't it?
    Oh, this is nothing! Check out Dagfinn Reiersøl's Design Patterns Gone Berserk

    Love it!

  21. #71
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, I'm pretty happy with this, so I wanted to post it. Doing it like this, the Front Controller doesn't know anything about the FilterManager, and the filters don't need to extend or have specials methods to execute the next filter.

    EDIT: I take that back, the filters *do* need methods called execute, that accept the filtermanager instance.

    PHP Code:

    $fm 
    =& new FilterManager( new FrontController );
    $fm->addFilter( new OutputBufferFilter() );
    $fm->addFilter( new AuthFilter() );
    $fm->execute();

    class 
    FilterManager 
        
        var 
    $controller null;
        var 
    $filters = array();
        var 
    $pointer 0;

        function 
    FilterManager(& $controller) { 
            
    $this->controller =& $controller
        } 

        function 
    addFilter(& $f) {
            
    $this->filters[] =& $f;
        }

        function 
    execute() {
            
    $this->executeNext();
        }

        function 
    executeNext() { 
            if (
    $this->pointer count($this->filters)) {
                if( (
    $filter =& $this->filters[$this->pointer]) !== null ) {
                    ++ 
    $this->pointer;
                    
    $filter->execute($this);
                 }
            } else {
                
    $this->controller->execute();
            }
        } 


    class 
    InterceptingFilter {
        
        function 
    InterceptingFilter() {
            
        }
        
        function 
    execute(& $filterManager) {
            
    // pre filtering...
            // $filterManager->executeNext();
            // post filtering...
        
    }


  22. #72
    Non-Member
    Join Date
    Jan 2004
    Location
    Planet Earth
    Posts
    1,764
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Nice approach though I personally don't like the idea that you've to instatiate the class with the Front Controller ?

    Would have been better if you could simple use the class method to add it instead

    Can't actually see any drawbacks mind you, it's just a 'gut' feeling that's all

  23. #73
    SitePoint Guru
    Join Date
    May 2003
    Location
    virginia
    Posts
    988
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by mwmitchell
    <snip/>
    Matt
    In case anyone is interested, I've updated these files. This is how the filters and controller is implemented (below). It does allow you to pre-filter, execute controller and then post-filter.

    PHP Code:
    require_once('FilterManager.php');
    $fm =& new FilterManager();

    require_once(
    'FrontController.php');
    $fm->setController( new FrontController() );

    require_once(
    'OutputBuffer.php');
    $fm->addFilter( new OutputBuffer );

    require_once(
    'RequestStripSlashes.php');
    $fm->addFilter( new RequestStripSlashes() );

    $fm->execute(); 
    Last edited by Mittineague; Dec 18, 2010 at 00:10. Reason: pre-new-sticky cleanup

  24. #74
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  25. #75
    SitePoint Member
    Join Date
    Aug 2004
    Location
    On the computer
    Posts
    23
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hello,

    Viewing this "advanced php" forum was quite a surprise to me. I have never heard of mvc before, um, yesterday. so I was trying to read through some of the threads, trying to research some on google, getting confused...but this thread helped out a lot I believe. btw I was up till 6 this morning researching..

    Anyway, I do have a few questions (if I can remember them).

    I thought the intercepting filter example was quite nice. One question though. Say you have some pages that require authentication, and some that do not, and they are all taken care of by this front controller?

    For example, you have a section where anyone can view the results of something, like a listing of products, for example. But only registered and logged in members of that site may add, delete, or edit. So then the authentication filter would be needed in some instances, but not in others. How would you take care of that situation, which would not be uncommon at all?

    um, and the model. there was no example of a model.

    so would the model basically have the methods to perform all the tasks the different pages require? That is, editing, deleting, and listing the data of a particular table.

    And also, I want to see if my understanding of these objects is correct. I didn't think that the view is supposed to have any knowledge of the model, but that the controller should take care of receiving the data from the model and passing it to the view? kind of the tie between the two. would that be right?

    I'm interested in a previous comment about a replacement to ModRewrite. You didn't explain further though, and so if possible I'd like a bit more of an explanation. I'mr efering to the comment that stated how you could change:

    index.php?page=whatever

    to

    /site/whatever

    Alright that's all from me.


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
  •