SitePoint Sponsor

User Tag List

Results 1 to 23 of 23

Hybrid View

  1. #1
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    The Response Object in an MVC implementation

    Hello everyone,

    I was babbling with a fellow PHPer about the Response object and how it fits inside a front controller | application controller | model | view implementation of PHP.

    I've seen it mentioned in other threads, but it was never denied or confirmed that it was right.

    Basically what I see happening is this:

    1) The front controller is instantiated agregating an Empty Response object (which is just a data space) and a Request object (which is a wrapper for URI and POST data).

    PHP Code:

    $fc 
    = new FrontController(new Request(), new Response()); 
    $fc->run(); 
    2) The front controller reads the request and Composes an Application Controller based on the first segment of the URI which has been mapped as "Controller" in the request object. The Response and Request Object is passed into the Application Controller during composition.

    3) The Application Controller uses the Request object to select a method to run. (I'm still a little scared of the Command pattern, I get the feeling that I'll get lost in all the commad files and my multiple application controllers would seem redundant when I use this pattern) - this is for another post however, let's just suffice to say that the Application Controller selects a method to run from itself using the second segment of the URI which has been mapped as "Action" in the request object.

    4) Inside the action/method called, a model is created using factory method


    PHP Code:
    class Base_App_Controller 
        
    extends App_Controller
    {

    //... other classes here

    private function _get_model($model) {
        
    $model ucfirst($model) . '_Model';
        return new 
    $model(DB::get_instance(), $this->_response);
    }

    5) Each Controller method is mapped to the Action parameter (which is the second segment) in the URI and manipulates the model.

    While it gives commands to the model through the model's public methods, the controller lets the model do all the the processing required to prepare the data for the View.

    PHP Code:
    class Some_Controller 
        
    extends Base_App_Controller
    {
        public function 
    index()
        {
             
    //...
        
    }

        public function 
    edit()
        {
             
    $this->_get_model('Some_model');
             
    $this->_model->get_list();
        }


    Here is where the Dillema is regarding the Response, Model and Request.

    I could go about it three ways:

    First and foremost, how I am actually doing it now - forget about the Response Object for a moment -

    The controller makes one or two calls to the model which initialises it. Basically, commands it to initialise itself. For instance, a public method call from the controller (eg $this->_model->getUserData()) could abstract calls to the the following private methods:
    - get_gateway() Get a Table Data Gateway
    - get_by_id() Get this by ID,
    - $this->set('userdata',$row_data_gateway) Store the Row Data Gateway object in your hash map as 'userdata'.

    The model sets itself up and stores data in its own hash map.
    The Model is then passed through to the view by the controller after the model is initialised with the $this->_model-.getUserData() call.

    The View aggregates the model and accesses data through its public hash map method (get()).

    The View is then acquired from the Application Controller and is invoked by the front controller.


    Second approach - The model uses the Request object as its data storage, when the command is given, the Model is actually populating the request object with the Objects, Variables etc.

    The View is then given the Request object instead of the Model and the View reads data from the Request object.

    Again, the View is invoked by the Front Controller after being acquired from the Application Controller.

    Consequently this makes me feel like I've tainted the Request Data with Response Data and separation is kind of defeated at this stage.


    Third approach - The one I'm kind of considering more than the second approach. The model manipulates data and stores it inside the Response Object.

    The response object is changed by the Model.
    The response object is read by the View and modified by the view.
    Once this is all done, The Front Controller outputs the response.

    Which of the three is the correct way? Is there something I've not thought about? rules I've broken? if so then what IS the correct way?

    Is there a UML diagram or article that would make everything "oh so clear"?

    I've searched around as always, I spend days doing RnD before asking. But I guess I'm using the incorrect keywords. :/

    Please enlighten me, thank you in advance.


    Regards,

  2. #2
    Non-Member
    Join Date
    Jan 2003
    Posts
    5,748
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    > The response object is read by the View and modified by the view.

    I think the Response could be the View in it's self in that event (third option) no?

  3. #3
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    Thanks for takin' the time Dr L.

    I think the Response could be the View in it's self in that event (third option) no?
    I thought as much, but if I looked at it like so, then the model would have no business manipulating it? - still unsure...

    At this stage, the Response object is more like a Data Container a well known object from
    Front Controller,
    Application Controller which tramps it over to the
    Model, when the model's done with it, it's passed to the
    View which pours yet more data into it.
    The front controller then displays the acquires and outputs the response in the end.


    Regards,

  4. #4
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by melancholic
    I thought as much, but if I looked at it like so, then the model would have no business manipulating it?
    I don't think the model has any business manipulating the response anyway. That would be a job for C/V. I recommend you come up with some other mechanism. For starters, how about getting rid of the Request/Response combo in favour of a ServiceLocator? Not all needs in your application will fit in them, of which this very problem is a fine example.

  5. #5
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Ezku.

    Obviously I'm looking at it the wrong way...
    Back to the old drawing board I guess...

    One last thing though, how would you use the service locator in this context? Can you please shed some light for me on this subject?

    regards,

  6. #6
    SitePoint Zealot
    Join Date
    Aug 2005
    Location
    South Africa
    Posts
    185
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    The service locator could work something like the following,

    PHP Code:
    $locator = new Locator();
    $locator->set('resuest', new Request());
    $locator->set('response'$response = new Response())

    $fc = new FrontController();
    $fc->run($locator);

    $response->out(); 
    Obviously the above implies that you are parsing your service locator around.

    --
    lv

  7. #7
    SitePoint Evangelist
    Join Date
    Mar 2005
    Posts
    423
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Using a servicelocator might give you slightly more streamlined interfaces, but i still don't see where or how you use a request object in the mvc architecture. Is it a container for the rendered view? Or simply used for redirects/ 404 errors?

  8. #8
    SitePoint Guru
    Join Date
    May 2005
    Location
    Finland
    Posts
    608
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skinny monkey
    Is it a container for the rendered view? Or simply used for redirects/ 404 errors?
    In most solutions around, the Response is used to hold the response body and take care of HTTP headers, status codes, redirects etc. It is usually manipulated in the Controller layer, and can be subjected to modification after actual generation by eg. intercepting filters.
    Edit:

    Did you actually mean Request and not Response?
    Last edited by Ezku; Jul 4, 2006 at 04:02.

  9. #9
    SitePoint Wizard Ren's Avatar
    Join Date
    Aug 2003
    Location
    UK
    Posts
    1,060
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by skinny monkey
    Using a servicelocator might give you slightly more streamlined interfaces, but i still don't see where or how you use a request object in the mvc architecture. Is it a container for the rendered view? Or simply used for redirects/ 404 errors?
    Request contains values that a controller uses to build the model. Or change the model for POST requests.

  10. #10
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by melancholic
    Which of the three is the correct way?
    I'd rename your response object "ViewDataContainer" or something. It's easier to tell at first glance what the object is all about.

    A container could be useful to round up data held in a series of different objects but I might be more inclined to pass domain objects to the view rather than a data container to domain objects.

  11. #11
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by lv
    Obviously the above implies that you are parsing your service locator around.
    Thanks LV, I must say, I've only just started experimenting thorougly with Polymorphism, and your example reaffirms some things.

    Quote Originally Posted by McGruff
    I'd rename your response object "ViewDataContainer" or something. It's easier to tell at first glance what the object is all about.

    A container could be useful to round up data held in a series of different objects but I might be more inclined to pass domain objects to the view rather than a data container to domain objects.
    That's exactly how I was seeing it, ViewDataContainer but all this reading up on other frameworks and implementations that use Response Objects got me thinking that the response object actually IS the container.

    Is there a reason why you are more inclined to pass domain objects to the view than a container to domain objects? or is it merely through personal preference?

    Since the Response Object is not what I thought it was, can someone please clarify as to what it really is?
    Is it really the view as Dr L had first mentioned?
    Or is it one of those "it CAN be" considered as a View things?

    Thanks for the input. I'm very grateful.


    Regards,

  12. #12
    simple tester McGruff's Avatar
    Join Date
    Sep 2003
    Location
    Glasgow
    Posts
    1,690
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by melancholic
    Is there a reason why you are more inclined to pass domain objects to the view than a container to domain objects? or is it merely through personal preference?
    I thought it might be less likely to lead you away from nice, cohesive view classes. In MVC a view is responsible for collecting its own data - often it's observing some other object(s). Passing a data container around might lead you into trouble. Domain objects (or the controller) should not know anything about the display and should not place data in the view. You don't have to write MVC of course.

    If a view has references to a bunch of domain objects pretty much all it has to do is include a template and you're done. If it's observing it may need to receive and interpret messages but again that's often pretty simple. What's the argument for a data container?

    Since the Response Object is not what I thought it was, can someone please clarify as to what it really is?
    A Response object is anything which you define it to be. To me Response conveys a sense of "everything done in response to a request". That will of course include a view but might also include other actions such as emails. To keep faith with the game plan of MVC, other actions in addition to the view should be similarly decoupled from the controller and from each other as far as possible. That gives: model / (independent) actions / controller (better still: assembler / model / actions / controller).

    As discussed above, Response is in fact the view. Anything involved in collecting viewable data and sending an http response to a browser is part of the view - including output compression for example.

  13. #13
    SitePoint Guru 33degrees's Avatar
    Join Date
    May 2005
    Posts
    707
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The Request object represents data coming from the browser, and the Response object represents the data that will be send to the browser. As such, it's the interface between the view and the browser, and contains everything output by the view; print statements, headers (including redirects) and the like. It has nothing to do with the model, or passing data TO the view, only storing the result of the view.

    There are a couple of advantages to this approah. One is that you can run filters post view, that would interact with the response object to change it's data. This could be output compression, or character set modifications. Another advantage is that headers are sent at the last moment, so that the can be changed or aborted at any time. For example, you may be wanting to do a redirect, but after you call the redirect method, an error occurs and you want to display an error.

  14. #14
    SitePoint Zealot
    Join Date
    Aug 2005
    Location
    South Africa
    Posts
    185
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I currently use a response object to manage what needs to be returned from the controllers. Depending on what the controllers decided your reponse could return a views rendered info, extra page headers, page redirects etc. Pretty much what Ezku and 33degrees communicated.

    As an example you could have something like:

    PHP Code:
    $response $locator->get('response');
    $template = new Template('index.tpl.php');
    $template->set('web''www.sitepoint.co.za');
    $response->setRenderer($template);
    // OR
    $response->setContent($template->render());

    // later in your index.php (your front controller calls)

    $response->execute($locator);
    $response->out(); 
    However the above depends on what you want to achieve with your response or viewcontainers in a sense.

    --
    lv

  15. #15
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the "responses" 33Degrees and LV, (no pun intended :P)
    Definitely gave me some much needed insight into the subject matter.

    I'll be refactoring and hopefully come up with a semantic implementation...


    Cheers,

  16. #16
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok, messing around with argouml... I've drafted up a class diagram... here's the zipped zargo file if anyone's interested

    My UML is a little rusty, (for instance, I did not know how to indicate usage) so please feel free to correct me if anything is wrong.

    Are there any improvements I can make to this design?

    Here's the short story

    The Request Object represents the data that's been fed into the Application (URI's & Post data)
    The Response Object represents the data that's returned by the Application and is outputted by the Front Controller once the work has been done.
    These objects are used by the Front Controller which delegates responsibility of handling the Request to the Application Controller.
    The Application Controller would select a specific Command/Action which is either encapsulated as methods within the itself, or delegate to a Command or Action Object.
    The Command or Action object then creates a model, manipulates the model and then passes the model to the View in the View's Constructor
    The View uses the data in the model to render the HTML to be displayed when outputting the Response.
    The Front Controller takes all this information and puts it back into the Response Object.


    Regards,
    Attached Files Attached Files

  17. #17
    SitePoint Evangelist
    Join Date
    Jun 2003
    Location
    Melbourne, Australia
    Posts
    440
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Err... mvcumlxx.zip, when unzipped on MacOSX, gives a file mvcumlxx.zargo and is unreadable. Any ideas?
    Zealotry is contingent upon 100 posts and addiction 200?

  18. #18
    SitePoint Zealot DerelictMan's Avatar
    Join Date
    Oct 2005
    Posts
    123
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by auricle
    Err... mvcumlxx.zip, when unzipped on MacOSX, gives a file mvcumlxx.zargo and is unreadable. Any ideas?
    That file extension is used by ArgoUML...

  19. #19
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I thought it might be less likely to lead you away from nice, cohesive view classes. In MVC a view is responsible for collecting its own data - often it's observing some other object(s). Passing a data container around might lead you into trouble. Domain objects (or the controller) should not know anything about the display and should not place data in the view.
    Thanks for pointing that out. You gotta understand, I'm still wide eyed with dumb ideas at this time as I have not experimented enough.

    I know there are other options to MVC, but I just want to get my head around this properly so I can make a learned choiice of when and when not to use it - that plus it's just one of those things that I'll always be wondering about.

    After reading and re reading some things, I think I might have to change some more things in my design.

    I guess in the current design, what I'm refering to as the "View" is more like a "View Helper" object.

    I mean, it practically IS a Template class, well actually it's more like a combination of a View Helper, Template and Response in a sense because it actually does the following:

    - Select up a Template file
    - Puts together data to be displayed using setParam() method
    - Outputs itself to the browser.

    The template file (which is a static PHP file included in the display() method) reads data by using the getParam() method.

    At this stage the Class that I am refering to as a View Class is extended and private methods which use the Model are created ad hoc to collate and assign data which are then called by from the template file. (errr did I just repeat myself?)

    What I'll be doing at this stage is Refactoring my View Class to be three objects in a sense.

    View Helper - stays an abstract class which accepts the model in its constructor. This Class is to be extended with action specific helpers which have the methods to collate data using the model and populate the Template parameters.

    Template - Populated by the View helper, the getParam(), setParam(), output and template will be moved here.

    Response - Headers will be an array, Body will be a string, I'll be using output buffering to store the template's output in the body.

    Something like the attached UML diagram. For those who do not have ArgoUML, I've also attached an image.

    before.png = current design
    after.png = proposed design
    mvcumlxxx.zip = zipped zargo (ArgoUML model) file

    Will this be a better way of doing things you think?

    Thanks in advance guys.

    Regards,
    Attached Images Attached Images
    Attached Files Attached Files

  20. #20
    Non-Member melancholic's Avatar
    Join Date
    Nov 2004
    Location
    Australia
    Posts
    447
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    whoops messed that one up... forgot to remove methods out of view helper.
    Attached Images Attached Images

  21. #21
    SitePoint Enthusiast
    Join Date
    May 2009
    Posts
    29
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by melancholic View Post
    PHP Code:

    $fc 
    = new FrontController(new Request(), new Response()); 
    $fc->run(); 
    I like the approach of this. I am currently in the middle of designing my own MVC and I am encountering some approach-dillema's as well. I have one page that is a members-profile page and has arguments that need controller actions (video, blog, etc)

    Let me share some (probable) urls:

    domainname/member/(view)/1/
    domainname/member/(view)/1/video/10
    domainname/member/(view)/1/blog/7

    I could leave (view) out as i use it as the default state.
    Now let's try these, which will work fine, but the URL doens't really represent what it does.

    domainname/member/edit/1/
    domainname/member/edit/1/video/10
    domainname/member/add/1/video/
    domainname/member/edit/1/blog/7

    - member/1/add/video,
    Adds a new video to member 1's, but it reads as if it might add 1 video

    I am trying not the use a routing array or something like that. I would like to have the methods somehow to all belong to the members_controller.

    I am considering to have a members_controller (view states only, public) and a account_controller (view, add, edit, delete states), but I can't figure it out quite. I want the way to set it up to be as transparent as possible. A sortof WYSIWIC - What You See Is What It Controls

  22. #22
    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)
    This thread is three years old. You'd probably get better feedback if you started a new thread.

  23. #23
    SitePoint Enthusiast
    Join Date
    May 2009
    Posts
    29
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the mentioning.


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
  •