TIP: Use Markdown or, <pre> for multi line code blocks / <code> for inline code.
These forums are read-only and for archival purposes only!
Please join our new forums at discourse.kohanaframework.org
HMVC Discussion
  • Hey all,
    I have been reading about HMVC, and am still confused on what makes it more special than regular MVC. My understanding of HMVC is you can stack MVC triad blocks on top of eachother then based on the user environment the application will perform different behaviors. Which to me you could already do in regular MVC. I know that description is a little "hand wavy," and maybe wrong so I was wondering if someone could clearly state what the major difference between MVC and HMVC was and maybe provide some clearer reading material and an application of HMVC that MVC just wouldn't work.

    I have already looked at some of the other forum discussions that reference the SUN Java tutorial on HMVC(which I have read completely a couple times) but that didn't really translate too well for me. Thanks.
  • I'm not completely familiar with HMVC, but I think HMVC can be compared to AJAX on the server side; where your controllers can send requests to other parts of your application without requiring additional requests or redirecting the user to a new page.

  • MVC only has 1 controller per request, HMVC can have many.

    MVC request processing:

    1. bootstrap, determine uri
    2. route and load controller
    3. display output

    HMVC request:

    1. bootstrap, determine uri
    2. route and load main controller
      1. create request, route, load controller
      2. create request, route, load controller
      3. ...
    3. display output

    Basically, at any point within an HMVC framework, you can do something like this:

    <?php echo Request::factory('users/login') ?>
    <?php echo Request::factory('search') ?>
    

    Each request is entirely self-contained, as if someone went to (for users/login) http://example.com/users/login. It's very similar to AJAX, except that all of the requests happen within the main request.

  • jeje.. this remained me of include().

    Now -more seriously- I'm sure there is a good reason for going HMVC.
    I just don't get it by the moment. I will have to go studying.
  • Don't make the mistake of using the HMVC paradigm in stateful applications and applying it to web applications. This essentially applies to MVC in general, by nature it'll be different on the web compared to stateless apps. HMVC as is shown in Kohana, (someone here once termed MVC-pull, perhaps that's more applicable) is not like in Java. The whole triad concept doesn't really work on the web, nor does that really matter.

    HMVC as implemented here serves several purposes. First of all, it might be used for widgetized webpages; page elements that hardly have interaction with each other, a calendar together with a shoutbox, rss feed etc. To not clutter your controller, views too much the subrequest might be useful.

    Another purpose that I find more important is a stricter separation between the front controller and the action controller. The bootstrapping of Kohana is less intertwined with the handling of the request. The request handling is something that the Kohana core no longer handles but is delegated, this makes Kohana more loosely coupled. Further abstractions can of course be made but most probably at the expense of speed. (See Zend Framework with a Dispatcher, Router, Request (different kinds) and Response class) Having the request handling better embedded into Kohana also makes for easier testing. Without much difficulty you could set up a test for a form with the actual POST variables without the troubles of using an actual http request, but too use an internal request (an abstraction of an http request).
  • @dlib: Sorry I got a little lost in your description, how do you define a "front controller" and a "action controller."

    So is HMVC only really needed for "widgetizing" pages more effortlessly, or could it also help cutting down HTTP traffic? With your comments the java world article is starting to make more sense, in that they were only showing HMVC in terms of UI.

    Thanks for your responses.
  • @jshaw86

    A "front controller" is just the first file to execute the request. It is the "doorway" into the framework. In 99% of the cases, the index.php file will be the front-controller, but this file can be called anything, as long as it's called by the web server. It "launches" the framework.

    An "action controller" is the controller called by the request, either directly, or indirectly through url rewriting or custom routes.

    Example:

    http://www.site.com/index.php/foo/bar
    is the same as:
    http://www.site.com/foo/bar

    It's just that most devs suppress the display of index.php (the front controller) to keep the url very clean. And "foo" is the action, which usually corresponds to a Foo controller.
  • @Coolfactor got it, never heard that lingo before thanks.
  • For anyone confused with HMVC, think of it as multiple MVCs running inside a container and each MVC can speak to one another.

    So if the footer you're printing has some variable that needs to change the title in the header, you can do it.

    Then the container gets rendered and that's your output.

    Amazingly modular I tell ya.
  • and as of right now can this be done correctly with kohana? the Component library allows us to call multiple controllers but it feels very hackish and limited.
  • Check out dlib's Dispatch library for a potential solution. As of right now, neither trunk or pre_3.0 support HMVC.

  • right, component is dispatch for the pre_3.0 branch
  • [deleted]
  • Sorry to bring this old post back, since 3b1 is out I have been looking over the Request object and I came up with an example that I think shows the usefulness of HMVC.

    So I have been working on standard MVC web app that uses it's own messaging system. Throughout the MessagingController methods (inbox,compose,draft), there is a address book that shows up(in the template view). Currently these 2 controllers are mutually exclusive,loading the addressbook is done by creating an instance of the AddressBook model in the messaging controller and calling the method that lists the address.

    In MessagingController, __construct method

    $address_book_model = new AddressBook;
    $contacts = $address_book_model->get_contacts();
    //pass these contacts to the template view to display


    If this was done in an HMVC ideology, to me, it semantically make sense to have a request instance of AddressBookController inside MessagingController like this

    In Controller_Messaging, probably in the __construct:

    $contacts= Request::factory('addressbook/contacts')->execute();
    //from here pass the contacts to the messaging template view to display the contacts on render



    In Controller_Addressbook, contacts method:

    public function contacts(){
    $address_book_model = new Models_AddressBook;
    return $address_book_model->get_contacts();//would get all contacts for the particular user
    }


    Does this make sense?
  • Not exactly, since the return value of controllers is meaningless.

    Here is a nice simple way to thinking about it. Say you have a login box on every single page. Rather than having to build login functionality into every controller, you could simply do this in your template:

    <?php echo Request::factory('user/login')->execute() ?>
    

    And the controller that responses to that request would do nothing except display a login form. All the POST data would already be part of the application, so errors and such would automatically be rendered.

    Hope that makes sense.

  • ahah that's exactly what I was looking for a couple of months ago... building a login "module" that could be exported easily on all my apps. With 2.X.X branch you can't (at least not that easily). Definitely interested in 3.0 :) This example is perfect to show the power of HMVC
  • Posted By: Shadowhand

    Not exactly, since the return value of controllers is meaningless.

    Here is a nice simple way to thinking about it. Say you have a login box on every single page. Rather than having to build login functionality into every controller, you could simply do this in your template:

    <?php echo Request::factory('user/login')->execute() ?>

    And the controller that responses to that request would do nothing except display a login form. All the POST data would already be part of the application, so errors and such would automatically be rendered.

    Hope that makes sense.



    But you would be able to do that anyway with libraries and helpers.
  • I'm also interested to know how both the conceptual and practical advantages of HMVC outweigh libraries and helpers.
    Cheers.
  • What is the added overhead though of doing

    <?php echo Request::factory('user/login')->execute() ?>
    

    over just using a library or helper to include it? It seems like there must be a lot more overhead.

  • Well the most obvious answer is that all requests happen through the same place, so the logic will be exactly the same. In terms of overhead, there really isn't that much. The "heavy lifting" is really all in Request::instance() which is only executed for the very first request.

    You can still include views directly by using include Kohana::find_file('views', $path), but that does not give you all of the controller logic that goes with a particular view... and you certainly should not be putting validation logic in your views!

  • I use it in a web app that renders graphs and charts based on data from external machines. Basically it works like this:
    User ---- HTTP Request ----> Initial Controller ---- Internal Call ----> Another Controller
    Initial Controller < ----- Return ---- Another Controller
    User
  • @dcunited that's called Kohana 3, your main controller would probably look something like this:

    $this->request->response = json_encode(Request::factory('report_controller/controller_action')->execute()));

    (correct me if i am wrong shadowhand)
    I'm not sure if the json helper will be supported or not in KO3, but that should be close to what you are looking for.
  • @dcunited08: That is exactly what the HMVC support in Kohana v3.x provides.

    @jshaw: I think you could drop the json_encode call, as that would be handled in the controller itself. But that is basically spot on.

  • So okay, if I get this right.

    Say on some websites like digg.com you see there is always a login box. You could use the hmvc to include the login action on say the home page action or pages that need authentication. When they execute the form it'll send them to the "auth controller, login action" (user/login) page and work like that. So it's practically just getting the view content from the action you would normally request. So I guess it'll let you instead of redirecting a user more it'll let you do what you want on that page without actually having to send the user to another controller action (Like login form or a 404 ). I guess this is the more practical way of doing shit and cutting down on repetitive code. I kind of like it.
  • I hereby accuse humans, over-thinking creatures, in abusing luxurious words or abbreviations in order to sugar coat stuff they are trying to promote. Indeed, is it morally acceptable to use SPRIG, HMVC, etc...? Aren't we just restricting the field of K3 users to some fancy abbreviation knowing experts? To remedy the situation, let's take a little hint from Lamonte's simplified and down to earth lingo and change 'The swift PHP framework' to....

    Kohana 3.0
    The more practical way of doing shit
  • Lamonte you could use HMVC for a login box but it should only take care of the login box views because the login box request is going to be executed after the action request gets executed, which makes you spill memory and bandwidth.

    In your case it's better to extend the (template) controller and add the login check to the before function and make all the controllers that have actions that need authorisation children of that extended controller. If it needs to be displayed on all pages then you have to make all your other controller children of that extended controller.

    I think HMVC in Kohana is good for page pieces that have no connection with the content but aren't static (last comments, most read) or pieces that only need data set in parent controller (user chat, read by friends) and are displayed on more than one page.

  • I've recently created a e-commerce platform for a client using Kohana 3.0, which i used HMVC for the shopping basket and login bar widget. Its possible to do using libraries / helpers etc. i just find it easier, and more convetional to let the controller manage output.

    Sadly for security reasons i will not be releasing the source.
  • I'm in the process of choosing a good base platform for my own ideas very close to what is being said here
    monday I tested CI
    wednesday I tested Kohana 2.3.4
    today I'm intreged about K3.0 ; probably trying it out tomorrow

    I think I'm starting to understand the HMVC with this post, and it's interesting

    but I'm wondering can't all these modular elements be called individually using Ajax just like mashups would do ? (which would be an normal MVC)
    my second question is if multiple controllers are called from one initial call , I don't understand how or who deals with the different responses ?
    maybe I'l undersatnd while testing
  • @oceatoon: I was in the same road you are now, last September. Finally, Kohana 3 fulfilled all my needs :)

    I think you got a little confused there, HMVC doesn't have anything to do with Ajax. HMVC is basically a structural idea which is executed in Kohana 3 in a way that lets the developer "divide" his code into segments often called "modules", which each one is generally a "min-MVC" application by itself. Its not only the modules, but the way the request flows through the application and adheres to this structural idea called "HMVC". Kohana 3 has a neat OOP structure based on "factories" and "helpers", each factory has his purpose in receiving, computing, and delivering requests around the routing system (which is another cool thing about Kohana 3 -> Routes). I think the HMVC structure is really cool, it gives your applications an organized feel, lets you plug in and out re-usable code easier, and enables cleaner code with less tangles.
  • Posted By: oceatoon

    but I'm wondering can't all these modular elements be called individually using Ajax just like mashups would do ? (which would be an normal MVC)


    Absolutely. Except with HMVC, the mashups are built server-side. Less http requests and no dependency on javascript.
  • I've been reading up on HMVC, trying to decide if it's a good thing to try for my next project. Surprisingly, no one here has mentioned what HMVC stands for, which also gives some clues as to what the difference between MVC and HMVC is. HMVC stands for "Hirearchical MVC". Therefore, I've sort of been thinking of HMVC as a hirearchy of MVC modules. You can basically have a typical piece of MVC code that in turn calls other full-fledged MVC "triads" directly through their controllers (each of which can in turn execute a completely separate bunch of code, possibly running code that is completely unrelated to the main request). In a standard MVC style web app, the controller actions are initiated by a single web request, so if you can't initiate sub-request to call other controllers in the middle of your main request, then you are SOL when it comes to reusing that functionality. With HMVC, you can basically initiate an internal Kohana request on the server side from within a controller. This would bypasses the typical web request and call that functionality without making another client-side request. So that's why people are thinking of this in terms of widgets or AJAX without the extra request...you could create all your interface elements as standalone MVC modules, each with their own Controller, Model and View, then basically use those as widgets in another "main" controller which makes internal requests to them. These are not "REAL" web requests as most of us think of them as they are not initiated by the browser and do not result in another round of request/response between the client and server. At least, that's my understanding.

    So how might this make my life easier? Well, I was just trying to come up with an example and I got to thinking about the Minify library on Google Code. I tried to integrate this as a library in Kohana 2.x and it was a rather hackish endeavor. I dropped the files into my libraries folder and ended up wrapping the entry point in in a helper function -- it worked, but didn't integrate very smoothly and I can't even remember how I did it now. However, the minify lib is designed to be super easy to install/use. You just drop it into your web root and then send requests to its controller (it has its own MVC thing going on) with a querystring containing a list of files to be minified. Usually people just change the "src" of thier js files to use that standalone minify url, but this causes another request/response roundtrip from the browser which is why I integrated it as a Kohana library. So, now I'm wondering, could I take advantage of HMVC to sort of wrap all that functionality into a Kohana request using the request::factory method or am I misunderstanding what this HMVC stuff is good for? I don't know the answer. Anyone here know?
  • So, now I'm wondering, could I take advantage of HMVC to sort of wrap all that functionality into a Kohana request using the request::factory method or am I misunderstanding what this HMVC stuff is good for?

    Kohana HMVC is very powerful as you rightly point out but it is limited to calling Kohana requests as sub requests. That means a sub request must be a Kohana controller and action. Also note that $_GET and $_POST are NOT set differently in the subrequest - there was a huge discussion about this a while ago on the forums and it is a good idea not to try and emulate /mess with the globals inside subrequests.

    You said "([Minify] has its own MVC thing going on)". It wouldn't directly be possible for Kohana to issue a sub-request to a different MVC framework. You would need to still have a kohana controller and action that wrapped up the Minify library functionality to be able to access it with a sub-request.

  • granted I'm a newb to frameworks, but HMVC to me is just lifting the "one route/one controller" limitation off of MVC. but I never really understood MVC to mean one controller per request anyway, and I don't think it does(?). I just thought it was confined that way due to how PHP MVC frameworks were built. (or the ones I had experience with). before I started using MVC frameworks I just built PHP websites using OO concepts, which naturally lead to many objects being instantiated on each request, each object handling varying degrees of model/view/controller responsibilities. my route handling was always very flexible but not so automated and beautiful like KO3. a route might just call a single method with a single argument, or it might use multiple objects all willy-nilly to get the job done. HMVC just kind of makes you organize your wild OO desires back into the MVC paradigm, as to be more organized, maintainable and portable.

    i don't think every little login/shopping cart component of a website really requires an entire MVC triad though, not that KO3 implies that. it just makes it possible.

    as for Minify, Swiftmailer, etc.etc. external libraries... it's funny to me when people get so wrapped up inside of a framework that they can't really think straight PHP anymore. I can see where having a helper is nice because it might keep the API consistent across multiple versions of an external library, but for something like Minify that has an actual HTTP interface, just use it like it's intended and don't try to force it into the overhead of another framework.
  • It occurs to me that if you want to pass a preformatted data array to a request, you can simply serialize it and add it to the url or post data.
    Is this "violating" the principle of HMVC or is it a smart timesaver?

    $validParams_serialized = urlencode(serialize($this->validParams));
    $list = Request::factory('list/' . $validParams_serialized )->execute()->response;
  • Probably best to save it in a session variable instead.

    Session::set('validParams', $this->validParams);
    $this->validParams = Session::get('validParams', NULL);

    This way you don't have to worry too much about cleaning the input from the uri and it does all the serializing for you. Also it provides a default value when its not set. I would never trust any data passed in a request URI or $_POST var.
  • Of course, if you really don't see the point of HMVC then don't use it, KO3 doesn't force its use. Far from it.

  • @felixhcat : if you want to pass a custom data to a request you could do it in a simple manner $request = Request::factory('your/uri'); $request->my_data = $my_data; $request->execute()->response;

    access your custom data as $this->request->my_data

  • access your custom data as $this->request->my_data

    though that wouldn't be true HMVC as it doesn't work for external requests, which is actually a good benefit of HMVC to scale "vertically".

    Please tell me if that is wrong.

  • @zsoerenm correct - in theory there should be no interaction between requests other than what could be done with a true http request. So you should pass data in GET, POST or session in the usual way.

    I'd also always be wary about setting a run-time property on a core class pike Request like that - can lead to very hard to debug issues.

  • It is worth noting that v3.1 has support for external requests and responses.

  • @zsoerenm yes it works only for internal requests.

    @andrewc It may be ok to have interaction between internal requests and don't mimic in all aspects a true http request. And yes we should pass data in GET, POST but those GET, POST should be isolated per each internal request.

    Perhaps a code like this // save original $original_POST = $_POST; $original_method = Request::$method; // overload $_POST $_POST = $new_post_array; $request = Request::factory('your/uri'); Request::$method = 'POST'; $request->execute()->response; // restore original $_POST =$original_POST; Request::$method = $original_method;

  • FWIW I'm experimenting with

     $request->transfer['somecontext'] = $somecontext;
    

    before calling, and

     $someconfigurationdata = $request->transfer['someconfigurationdata'];
    

    on return.

    I know this is somewhat contrary to the spirit of HMVC, and excludes external calls (though I presume with some work some kind of proxy system could be devised) but

    • there are advantages to HMVC for modularity of page construction for which I don't see a ready alternative, while at the same time

    • most widgets on my pages are coordinated in some way, and require sharing of internal configuration data which is somewhat peripheral to the main data

    At least $request->transfer is somewhat standardized.

    I'm wide open to ideas here though.

    A specific situation is co-ordination of main page contents with sidebar data operation controls (such as Allow, Deny, Hide, Show, Add, etc.) Another one is vertical partitioning based on the user route into a dataset, such as listing all articles in a table, vs just opinion articles or blogs.

    • Henrik
  • I tried assigning and retrieving custom data on $request, doesn't seem to work. Do the above posts still apply for Kohana 3.2? Are the alternate ways of achieving the same effect?

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion