SitePoint Sponsor

User Tag List

Page 1 of 5 12345 LastLast
Results 1 to 25 of 104
  1. #1
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The Controller in an MVC pattern

    Hello!

    After spending a couple of days reading about MVC (being new to object oriented programming) including this thread here on Sitepoint, I decided to have a go at implementing a very basic MVC design. I haven't studied InterceptionFilters or anything like that yet, I'm just going to focus on understanding the basics at first..

    I'll just post what I've got so far and ask the questions further down; seems easier that way. Here goes. (I'm using the name page for pageController/command. I do not know the correct term, more on this later)

    I have the following folders:
    /includes/
    /models/
    /pages/ (controllers)
    /views/ (should probably be called templates)
    index.php

    Includes holds my base classes, models my models, pages my "controllers/commands" and views my templates/views.

    Portion of index.php:
    PHP Code:
    function __autoload($class)
    {
        
    $path ROOT '/%s/' $class '.php';
        
    $folders = array('includes''models''pages');
        foreach (
    $folders as $folder)
        {
            if (
    file_exists(sprintf($path$folder)))
                return require_once 
    sprintf($path$folder);
        }
        return 
    false;
    }

    if(
    $_GET['page'])
    {
        
    $page 'page_' $_GET['page'];
        if(
    class_exists($page))
            
    $output = new $page;
        else
            echo 
    '404 page here';
    }
    else
        echo 
    'Default page here'
    A page or "controller": (/pages/page_users.php)
    PHP Code:
    class Page_Users extends MVC_Page
    {
        function 
    __construct()
        {
            
    parent::__construct();
            
    $this->user = new Model_User(); // Create Model
            
    $this->view = new MVC_View('users'); // Create View
            
    $this->view->title 'List Users';
            
    $this->view->users $this->user->ListUsers(); // Pass data from model to view
            
    $this->view->Output(); // Output everything to the screen
        
    }

    The basic view class (includes/mvc_view.php)
    PHP Code:
    class MVC_View extends MVC_Object
    {
        protected 
    $layout// Holds basic template
        
    protected $view// Holds the view
        
    protected $title;
        protected 
    $content// Parsed copy of $view

        
    public function __construct($view$layout 'layout')
        {                
            
    $this->view ROOT '/views/view_' $view '.php';
            if(!
    file_exists($this->view))
                throw new 
    exception('This view does not exist: ' $this->view);
            
            
    $this->layout ROOT '/views/view_' $layout '.php';
            if(!
    file_exists($this->layout))
                throw new 
    exception('This layout does not exist: ' $this->layout);
        }

        public function 
    Output()
        {        
            
    ob_start();
            require 
    $this->view;
            
    $this->content ob_get_clean();
            require 
    $this->layout;
        }

    And finally, a view (/views/view_user.php)
    PHP Code:
    <h2>Print users</h2>
    <p>
        Lorem ipsum...
    </p>
    <?php foreach($this->users as $user):?>
        User: <?php echo $user['name']; ?>
        <hr />
    <?php endforeach?>
    I just want to know if I'm on the right track or barking up the wrong tree entirely. My main concern has to do with the controller part, which, even after reading a lot of articles, I'm unsure about. From what I can understand, I'm using a so called FrontController (index.php) which passes the request (only GET in my example) on to a "something" (controller? command?) which loads the model and view that it needs and then outputs the whole thing.

    I am guessing here, but should I put all my "actions" inside the controller/command file? An example: I post a form. Index.php sends it to the controller which then looks something like this:
    PHP Code:
    class Controller_Car
    {
        function 
    __construct($_post)
        {
            
    $this->car = new Model_Car(); // Create Model
            
    $this->view = new MVC_View('addcar'); // Create View
            
    $this->view->title 'Add car';
            
    $this->car->AddCar($_post); // Run method like this
            
    $this->view->addcar $this->car->AddCar($_post); // Or like this, if you want to print confirmation in the view
            
    $this->view->Output(); // Output everything to the screen
        
    }

    Or, alternatively:
    PHP Code:
    class Controller_Car
    {
        function 
    __construct()
        {
            
    $this->car = new Model_Car();
            if(
    $_POST['addcar'])
            {
                
    $this->car->AddCar($_POST);
                
    $this->view = new MVC_View('caradded');
            }
            else
            {
                
    $this->car->ListCars();
                
    $this->view = new MVC_View('listcars');
              }
            
    $this->view->Output();
        }

    So many questions.. My head is all wobbly.. Lastly, I realize that there is no right or wrong when it comes to design patterns, you sort of come up with your own way of doing stuff. The above works, but I'm always interested in knowing if things can work better. And also if I've completely missed the mark.

    Cheers everybody
    Last edited by pakmannen; Aug 28, 2007 at 05:40.

  2. #2
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I don't like to follow rigid MVC patterns. I'd probably never have a 'model' folder and a 'controller' folder. While in my app designs MVC are all well separated, the business logic of the application also would play an important part in the nomenclature and over all architecture.

    But then, you said it. There is no right and wrong.
    Online Startups Insight for new entrepreneurs

  3. #3
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    I don't like to follow rigid MVC patterns. I'd probably never have a 'model' folder and a 'controller' folder. While in my app designs MVC are all well separated, the business logic of the application also would play an important part in the nomenclature and over all architecture.

    But then, you said it. There is no right and wrong.
    Aw come on, I'm not talking about folder structure. The folders are just to avoid initial confusion on my behalf. Remember that I'm new to this! (But please, I'd be glad to know how you've set up your structure)

    I just want someone to tell me if I'm on the right track or if I've misunderstood something completely. It's one thing to read about it, but it's a lot easier to understand things if you can ask people directly.

    Edit - Also, to clarify something. My 'views' are actually probably what people refer to as 'templates'. I only have one 'view' class. (Why do you need more btw?) So the folder 'views' should probably be called 'templates'.
    Last edited by pakmannen; Aug 28, 2007 at 05:42. Reason: Clarify..

  4. #4
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Views is the only component that should directly interact with the user.
    Online Startups Insight for new entrepreneurs

  5. #5
    SitePoint Addict Jasper Bekkers's Avatar
    Join Date
    May 2007
    Location
    The Netherlands
    Posts
    282
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pakmannen View Post
    Edit - Also, to clarify something. My 'views' are actually probably what people refer to as 'templates'. I only have one 'view' class. (Why do you need more btw?) So the folder 'views' should probably be called 'templates'.
    That depends on the output format (pdf, html, xls, xml, ical et cetera) and the way you structure your views. You chose for a template based solution, but others might want to generate their output with a php library. If you're using a template based solution and only output html you might be able so work with one view class.

    You might also want to note that the view usually gets the data from the model directly.
    Design patterns: trying to do Smalltalk in Java.
    I blog too, you know.

  6. #6
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    That depends on the output format (pdf, html, xls, xml, ical et cetera) and the way you structure your views. You chose for a template based solution, but others might want to generate their output with a php library. If you're using a template based solution and only output html you might be able so work with one view class.
    That's interesting to know. But since I'm only doing a basic one here I'm going to go with html-only for the output. Most articles tends to implement heaps of different classes which makes it kind of hard to grasp for a beginner. Better to discover yourself why you need the more "advanced" features. I'm still trying to understand the basics here.

    You might also want to note that the view usually gets the data from the model directly
    Really? I thought the controller was supposed to act as a 'middle man' between the models and the views?

  7. #7
    Grumpy Minimalist
    Join Date
    Jul 2006
    Location
    Ontario, Canada
    Posts
    424
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pakmannen View Post
    Really? I thought the controller was supposed to act as a 'middle man' between the models and the views?
    By the original definition, this is exactly what shouldn't happen. The Controller processes user input, and selects a View. The View gets data from the Model(s) in order to display proper output. The Controller doesn't know about the Model, the View doesn't know about the Controller, and the Model doesn't know about anything.

    Of course, everyone has a different idea of what "the" MVC pattern really is.

  8. #8
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Isn't that exactly what I'm doing though, if I would only change the name of my "controllers" to "views" instead? That way I have one controller (index.php) that doesn't know about the model, I have views (formerly known as page controllers) that doesn't know about the controller and models that know nothing.

    So to rephrase my former question: is it more correct to say that views act as a 'middle men' between models and templates?

  9. #9
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tarh View Post
    The Controller processes user input, and selects a View. The View gets data from the Model(s) in order to display proper output. The Controller doesn't know about the Model
    Say that you want to create a user. Obviously you have a model that does the inserting into the database. When the user clicks the create user button, is this not user input then? How can the controller process the input if it can not access the model?

    If the controller only selects a view, is it then here that the model gets called and inserts the newly created user into the database? Is it in the view that all the "processing" takes place? After which, of course, the view outputs, say an html page.

  10. #10
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tarh View Post
    By the original definition, this is exactly what shouldn't happen. The Controller processes user input, and selects a View. The View gets data from the Model(s) in order to display proper output. The Controller doesn't know about the Model, the View doesn't know about the Controller, and the Model doesn't know about anything.
    Per Martin Fowler's definition, the controller's responsibilities are:

    * Decode the url and extract any form data
    * Create and invoke model objects to process the data
    * Determine which view should display the result and pass on the model information to it.

    So yes, the controller *is* the middle man between the models and views; the controller is the only part that knows about the HTTP request, and therefore the only part that knows which model(s) should be displayed by the view.

  11. #11
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Tarh
    By the original definition, this is exactly what shouldn't happen. The Controller processes user input, and selects a View. The View gets data from the Model(s) in order to display proper output.
    Quote Originally Posted by 33degrees View Post
    So yes, the controller *is* the middle man between the models and views; the controller is the only part that knows about the HTTP request, and therefore the only part that knows which model(s) should be displayed by the view.
    Ah, great to see that people are disagreeing even on this fundamental level. Um..

  12. #12
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pakmannen View Post
    Ah, great to see that people are disagreeing even on this fundamental level. Um..
    The controller responds to User Events. The operation can be input or output, depending on the particular Event. The Controller however in no case should directly interact with either the User or the Database.

    Visitor Opens Website
    View Invoked -> Controller Called By View -> Model Called By Controller -> Initial Action -> Data Fetched -> Business Logic Applied By Model -> Data Sent To Controller -> Controller Makes Data View Friendly -> View Displays Data

    Visitor Fills Form, Hits Submit
    View Side Data Validation -> Input Sent To Controller -> Controller Side Data Validation -> Controller Converts Data To Model Readable -> Appropriate Business Logic Concept Invoked From Model Object (Input Data as Param) -> Model Does Its Thing -> Returns Result To Controller -> Controller Makes Result Data View Friendly -> View Displays Result
    Online Startups Insight for new entrepreneurs

  13. #13
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    Visitor Opens Website
    View Invoked -> Controller Called By View -> Model Called By Controller -> Initial Action -> Data Fetched -> Business Logic Applied By Model -> Data Sent To Controller -> Controller Makes Data View Friendly -> View Displays Data

    Visitor Fills Form, Hits Submit
    View Side Data Validation -> Input Sent To Controller -> Controller Side Data Validation -> Controller Converts Data To Model Readable -> Appropriate Business Logic Concept Invoked From Model Object (Input Data as Param) -> Model Does Its Thing -> Returns Result To Controller -> Controller Makes Result Data View Friendly -> View Displays Result
    I understand most of this, except the first two stages. (View Invoked -> Controller Called By View) The way I have it now looks like this:

    Visitor Opens Website
    Controller Called By FrontController -> Model Called By Controller -> Initial Action -> Data Fetched -> Business Logic Applied By Model -> Data Sent To Controller -> Controller Makes Data View Friendly -> View Displays Data

    The difference being, my Controller does not get called by the View anywhere but sort of the other way around. The controller creates a new View and, after having done its thing with the models, displays it.

  14. #14
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, the View should probably be the only component publicly accessible. So by default when the User visits the site, an instance of the view is initiated and loaded.

    Say I have two views for the same application - Flash based and the other one Html based. In either case, the user will first begin by entering the path to the Html file or Swf file.

    From there, let the View handle it as it has to by calling the Controller with default params. What is the need to expose the Controller to the User at all?
    Online Startups Insight for new entrepreneurs

  15. #15
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well there's subtlety. The controller is responsible for determining which models are required for the request, but then directly passes the model to the view, and then the view extracts the data it needs from the model; there's no need for the controller to take data out of the model and pass the data to the view. In other words, the view and the model aren't isolated from each other.

  16. #16
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Think of it as more of a concept. You have to create three distinct yet mutually components. Each has a place and a role. One common pit fall is to mix up the Business Logic and to spill it between all three components. That has been a major threat to almost every MVC project.

    Let's say my Business Logic for User Registration includes:
    1. adding an entry into the User Table
    2. adding an entry into the Profiles Table
    3. and finally Sending out a welcome email

    My View would:
    1. Contain the Form
    2. Perform Client Side vaildations
    3. Post Data to Controller

    My Controller would:
    1. Perform Server side validations
    2. Make data Model Friendly (entities decode, strip, split, push into array/object or whatever)
    3. Send data to the Model

    Model would:
    1. Insert row in Users
    2. Insert row in Profiles
    3. Send out welcome email
    4. Return result to Controller

    Controller would:
    1. Read result
    2. Convert result into View side display string (nice status message, language handling perhaps?) or code
    3. Pass result to View

    View would finally:
    1. Display result
    2. Enable the View (if it was disabled while the process took place)
    Online Startups Insight for new entrepreneurs

  17. #17
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    Well, the View should probably be the only component publicly accessible. So by default when the User visits the site, an instance of the view is initiated and loaded.
    Frankly, this is wrong. The view renders the data it is given, it's the controller that processes and responds to events. You use flash as an example of a view, but in fact a flash file is it's own MVC application.

  18. #18
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    Well there's subtlety. The controller is responsible for determining which models are required for the request, but then directly passes the model to the view, and then the view extracts the data it needs from the model; there's no need for the controller to take data out of the model and pass the data to the view. In other words, the view and the model aren't isolated from each other.
    What's the point of having a Controller then?
    Online Startups Insight for new entrepreneurs

  19. #19
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    What's the point of having a Controller then?
    As I posted earlier, the controller's job is to:

    * Decode the url and extract any form data
    * Create and invoke model objects to process the data
    * Determine which view should display the result and pass on the model information to it.

  20. #20
    Beer drinker Srirangan's Avatar
    Join Date
    Jan 2005
    Location
    Beerland!
    Posts
    776
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There ya go, that's what I said.
    Online Startups Insight for new entrepreneurs

  21. #21
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    There ya go, that's what I said.
    I actually didn't post that in response to you, but there were a couple of posts in between that one and the one I was responding to. Sorry for the confusion!

  22. #22
    SitePoint Addict
    Join Date
    Jun 2005
    Posts
    262
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by 33degrees View Post
    The controller is responsible for determining which models are required for the request, but then directly passes the model to the view, and then the view extracts the data it needs from the model; there's no need for the controller to take data out of the model and pass the data to the view. In other words, the view and the model aren't isolated from each other.
    Quote Originally Posted by 33degrees View Post
    As I posted earlier, the controller's job is to:

    * Determine which view should display the result and pass on the model information to it.
    Hi, 33degrees. In the prior quote you mention that the controller would directly pass the model to the view. In the latter, you say the controller should pass the model information. Would you please clarify?

  23. #23
    SitePoint Enthusiast
    Join Date
    Aug 2007
    Posts
    92
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Srirangan View Post
    Well, the View should probably be the only component publicly accessible. So by default when the User visits the site, an instance of the view is initiated and loaded.

    Say I have two views for the same application - Flash based and the other one Html based. In either case, the user will first begin by entering the path to the Html file or Swf file.

    From there, let the View handle it as it has to by calling the Controller with default params. What is the need to expose the Controller to the User at all?
    In my case, since I'm using a front controller, nothing is exposed to the user except that. All the other controllers, which generates views after being called by the front controller, have access restrictions. But I can see how it's possible to do as you say. I do not see how one method is better than the other.

    Quote Originally Posted by 33degrees View Post
    Well there's subtlety. The controller is responsible for determining which models are required for the request, but then directly passes the model to the view, and then the view extracts the data it needs from the model; there's no need for the controller to take data out of the model and pass the data to the view. In other words, the view and the model aren't isolated from each other.
    I think I disagree with this. Why pass the entire model object on to the view? The view should only need exactly the data it requires to render the view, is that not correct? The controller seems like the logical place to handle this.

    Quote Originally Posted by Srirangan View Post
    Think of it as more of a concept. You have to create three distinct yet mutually components. Each has a place and a role. One common pit fall is to mix up the Business Logic and to spill it between all three components. That has been a major threat to almost every MVC project.

    Let's say my Business Logic for User Registration includes:
    1. adding an entry into the User Table
    2. adding an entry into the Profiles Table
    3. and finally Sending out a welcome email

    My View would:
    1. Contain the Form
    2. Perform Client Side vaildations
    3. Post Data to Controller

    My Controller would:
    1. Perform Server side validations
    2. Make data Model Friendly (entities decode, strip, split, push into array/object or whatever)
    3. Send data to the Model

    Model would:
    1. Insert row in Users
    2. Insert row in Profiles
    3. Send out welcome email
    4. Return result to Controller

    Controller would:
    1. Read result
    2. Convert result into View side display string (nice status message, language handling perhaps?) or code
    3. Pass result to View

    View would finally:
    1. Display result
    2. Enable the View (if it was disabled while the process took place)
    I agree with this. Again, why pass the entire model to the view when the controller can (using Srirangan's words here) "Convert result into View side display string" before passing this information on to the View.
    Last edited by pakmannen; Aug 28, 2007 at 13:17.

  24. #24
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Umm...

    > What's the point of having a Controller then?

    Code:
    www.domain.com/controller/action/format/html/
    Code:
    www.domain.com/controller/action/format/xml/
    The point of the Controller is to decide what to do, based on a Request, as demonstrated by those sample urls above. Not only that, a given Request may be from $_GET, et al or it may be from a web service for example...

    > The controller converts the results from the model into a viewable form.

    I would think otherwise but I'm too tired to argue about it just now.

  25. #25
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by champ View Post
    Hi, 33degrees. In the prior quote you mention that the controller would directly pass the model to the view. In the latter, you say the controller should pass the model information. Would you please clarify?

    When I used the words "model information", I was paraphrasing part of martin fowler's description of the controller's functionality (he specifically uses the words "model information"). This is a bit ambiguous, but in his code examples he passes the model object itself to the view. As far as I've seen, having the controller pass the Model to the View is the common accepted definition of the pattern, and a quick google search bears this out:

    • Wikipedia's definition states that the View: "Renders the model into a form suitable for interaction, typically a user interface element."
    • http://ootips.org/mvc-pattern.html says: "A viewport attaches to a model and renders its contents to the display surface. "
    • http://www.enode.com/x/markup/tutorial/mvc.html says: "whenever a controller changes a view, for example, by revealing areas that were previously hidden, the view gets data from the underlying model to refresh itself."
    • Sun's description says "The view renders the contents of a model. It accesses enterprise data through the model and specifies how that data should be presented."


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
  •