SitePoint Sponsor

User Tag List

Page 2 of 3 FirstFirst 123 LastLast
Results 26 to 50 of 51
  1. #26
    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)
    I'm a little late to this party, so excuse me if I reiterate some points, but since my name came up I thought I'd just add a few clarifications.

    Quote Originally Posted by allspiritseve View Post
    Having a hierarchy of controllers also opens up opportunities for code reuse. A parent controller could be setting a datasource for a child controller, which means you could have the same child controller work for many parent controllers. I'm sure there are a lot more benefits than this, but wysiwyg or kyberfabrikken would probably be able to explain them better than I could.
    One of the things that works well with hierarchical controllers, is that it forms a coherent presentational unit. Amongst other things, this makes for a practical way of managing urls and url-propagated state in a transparent way to the rest of the application. It's a different way of cutting the presentation layer, than frontcontroller + mvc. Controllers (or components, as they are called in Konstrukt) tend to be smaller and control only part of the rendering of the page, while having a tighter coupling between controller and view layer. This means that you can't as easily change the view of your application, without touching the controller layer, but the benefit is that you gain a much tighter control of the http-level interaction. In many types of applications, I find that trade worthwhile, since it makes it easier to create a good end-to-end user interaction. It also does away with some (in some cases) redundant abstractions.

    Quote Originally Posted by matthijsA View Post
    The fact is that in the end it's always one controller and one action that are responsible for the response. So the question is, do you get to that controller/action set in one go or through several steps? In that last case controller A gets the first part of the URL. Can I handle it? No, forward to next controller. That one checks if it has to handle it as well. No? Forward again. Etc etc.
    With hierarchical controllers, you can spread the handling out over multiple controllers. In a Konstrukt application, you would usually have one "final" handler, which corresponds to the "action" of Rails. However, you would often have several parent handlers, which add a bit of rendering (Navigation for example) or provide contextual model level access for the final handler. This roughly corresponds to Rails "layouts", except that you're not restricted to one, and it isn't just for rendering the view.

    Quote Originally Posted by matthijsA View Post
    On one side it seems simple to use, but at the same time I wonder what happens if you want to restructure your whole URL scheme. If you have the scheme in a central place, it's easy to change. If it's decentralized, you have to change every part of it.
    Since components are completely contextual, it is quite easy to move them around. URLs are generated by refering to the parent component, so when a component is moved the urls will automatically change. In fact, you could use the same component in multiple places in your application at the same time. This is especially useful if you want to combine different applications, that weren't written for each other, because they won't fight over the same global resource (the route). In general, it's a more flexible and modular design; The problems with it is rather that it is slightly more abstracted. As a developer, you can't go to a single place and get an overview of all possible urls in the application.

  2. #27
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    It's an interesting approach and different from what you see in most frameworks like Zends. I guess there are certain advantages and disadvantages (as always) and which is more important depends on the kind of webapp you build

    One thing I do wonder about, if each parent handler is responsible for a certain part of the rendering (the layout with header and navigation for example), how do you feed back information from a child to its parent? For example the child controller will have information about the "current page or section", information that is needed in the parent to display in the navigation menu ("the currently selected menu item")

  3. #28
    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 matthijsA View Post
    It's an interesting approach and different from what you see in most frameworks like Zends. I guess there are certain advantages and disadvantages (as always) and which is more important depends on the kind of webapp you build
    Certainly. I'd say it shines most with a fairly complex, hierarchical interface. That generally means guis for applications, rather than web sites.

    Quote Originally Posted by matthijsA View Post
    One thing I do wonder about, if each parent handler is responsible for a certain part of the rendering (the layout with header and navigation for example), how do you feed back information from a child to its parent? For example the child controller will have information about the "current page or section", information that is needed in the parent to display in the navigation menu ("the currently selected menu item")
    A component knows the "remainder" part of the url (Called subspace), so you'd usually render the navigation in the component immediately parent to the final handler. I've build some applications with a gui that consisted of layered "tabs", where each component in the chain rendered a wrapping around each other. Works really well, because the graphical presentation mimics the logical structure of the application, making it easy to navigate in.

  4. #29
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Ok, sounds interesting. I have looked at Konstrukt in the past, maybe I should do it again and give it a better look.

  5. #30
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Correct me if I'm wrong, but as I understand it now, in Konstrukt each and every URL variable maps to a single controller. So there is no way a single controller handles more parameters?

    So an URL like
    http://www.site.com/hotels/in/englan.../2009/guests/2
    would mean I need to write 10 controllers?

  6. #31
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by matthijsA View Post
    Correct me if I'm wrong, but as I understand it now, in Konstrukt each and every URL variable maps to a single controller. So there is no way a single controller handles more parameters?

    So an URL like
    http://www.site.com/hotels/in/englan.../2009/guests/2
    would mean I need to write 10 controllers?
    I think so. But you should start by asking yourself: is that actually a Resource Locator, or are you throwing parameters (that should be in the query string) in the URL's path? A URL in my application would look like: /hotels/england/london/?date=16-03-2009&guests=2.
    Yes, I blog, too.

  7. #32
    SitePoint Evangelist
    Join Date
    Mar 2006
    Location
    Sweden
    Posts
    451
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by matthijsA View Post
    Correct me if I'm wrong, but as I understand it now, in Konstrukt each and every URL variable maps to a single controller. So there is no way a single controller handles more parameters?

    So an URL like
    http://www.site.com/hotels/in/englan.../2009/guests/2
    would mean I need to write 10 controllers?
    Not exactly. The default behaviour is that each segment is handled by it's own component, but you can override that so that basically only one component handles the whole chain. But as webaddictz wrote, the last segments there should really be query strings and not segments.

    I understand that it looks pretty to have a url like:
    http://www.site.com/hotels/in/englan.../2009/guests/2

    But what's the difference between this url:
    http://www.site.com/hotels/in/
    and:
    http://www.site.com/hotels/
    ?

  8. #33
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Well that URL is just an example, but I can think of more URLs with multiple arguments which could be defined as "query strings", but at the same time look better as segments.

    Just think of the average weblog with
    /category/php/2007/10/08/cool-routing

    Those arguments php, 2007, 10, 08 could all be defined as query string. But at the same time they could be a resource as well so
    /category/php/2007/10/shows all posts in category php from 2007 / 10

    I think I would prefer to write a single controller for handling archives, which would take the arguments for category, year, month, day and postname (or something like that) over having 6 controllers for each segment. Of course I am not familiar enough with Konstrukt to know how it works. But having 6 controllers each making a call to the "posts" model instead of having one controller making a call to the same model but then with different arguments doesn't sound too attractive to me.

    I do understand that the way Konstrukt handles things forces one to rethink and sometimes simplify the URLs. But I can also see situations in which you just want a different, more flexible and free URL scheme

  9. #34
    SitePoint Evangelist
    Join Date
    Mar 2006
    Location
    Sweden
    Posts
    451
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The default approach in Konstrukt is not to let all components call your model layer, as that would be terribly inefficient. You'd usually only let the final component call the model layer, as it knows that it's the final component. Or, you'd let a higher level component call the model layer, and the lower level components queries the higher level component for those objects.

    I absolutly agree that "/category/php/2007/10/08/" is a good url. Let's look at the differences of having one controller to handle all of the possible situations with that url, and having multiple.

    If you only have one, you'd have to have some conditional logic to check if the url is /category/php/2007/, or /category/php/2007/10/, or /category/php/2007/10/08/, as those three would require different views because they present different things.

    If you use three different components for this, you can place common logic in a higher level component, and let the Month component worry about months, etc.

    Besides, there's no requirement that each segment is handled by a unique component. It could be three objects from the same class, with some conditional logic inside to check for date parts.

    But I can also see situations in which you just want a different, more flexible and free URL scheme
    I actually feel quite the opposite. I see Konstrukts routing logic as the most flexible since your url mapping is based on logic instead of rules. And if you'd like, you can always let one component handle more than one segment (even though I've never found myself in a situation where that would be useful).

  10. #35
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    I actually feel quite the opposite. I see Konstrukts routing logic as the most flexible since your url mapping is based on logic instead of rules. And if you'd like, you can always let one component handle more than one segment (even though I've never found myself in a situation where that would be useful).
    +1 on that sentiment.
    Yes, I blog, too.

  11. #36
    SitePoint Zealot
    Join Date
    Jun 2004
    Location
    Netherlands
    Posts
    172
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    I absolutly agree that "/category/php/2007/10/08/" is a good url. Let's look at the differences of having one controller to handle all of the possible situations with that url, and having multiple.

    If you only have one, you'd have to have some conditional logic to check if the url is /category/php/2007/, or /category/php/2007/10/, or /category/php/2007/10/08/, as those three would require different views because they present different things.
    In this case I don't think there's any conditional logic needed or more then one view. You have one method in one controller which handles those parameters (probably as a bunch of "where X=Y" calls to the model layer)

    Quote Originally Posted by wysiwyg View Post
    I actually feel quite the opposite. I see Konstrukts routing logic as the most flexible since your url mapping is based on logic instead of rules. And if you'd like, you can always let one component handle more than one segment (even though I've never found myself in a situation where that would be useful).
    Well maybe I don't understand Konstrukt's ideas well enough. I've read the two tutorials on Konstrukt's site but yet fail to understand the philosophy/why behind the way it is set up (not saying its good/bad, just that I don't understand it yet)

  12. #37
    Theoretical Physics Student bronze trophy Jake Arkinstall's Avatar
    Join Date
    May 2006
    Location
    Lancaster University, UK
    Posts
    7,062
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    What it needs is a good ol' Video tutorial.

    CoderMaya did that with his framework and everyone LOVED it - because they understood it straight away.

    If Konstrukt had a video tutorial, I think it would help alot of people understand it better.
    Jake Arkinstall
    "Sometimes you don't need to reinvent the wheel;
    Sometimes its enough to make that wheel more rounded"-Molona

  13. #38
    SitePoint Evangelist
    Join Date
    Mar 2006
    Location
    Sweden
    Posts
    451
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by matthijsA View Post
    In this case I don't think there's any conditional logic needed or more then one view. You have one method in one controller which handles those parameters (probably as a bunch of "where X=Y" calls to the model layer)
    If the url only has a year, would you display that the same way as if the url had a year, month and day? That could be a very long list. And you'd probably want to write out the months as headlines above that months entries, which you wouldn't if the url contained a full date.

    I know that the concept behind Konstrukt isn't always that easy to understand (I know, because I was a user of Konstrukt before I was a contributor). But when I understood how it all worked, I basically never wanted to do it any other way.

  14. #39
    SitePoint Addict webaddictz's Avatar
    Join Date
    Feb 2006
    Location
    Netherlands
    Posts
    295
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by wysiwyg View Post
    If the url only has a year, would you display that the same way as if the url had a year, month and day? That could be a very long list. And you'd probably want to write out the months as headlines above that months entries, which you wouldn't if the url contained a full date.

    I know that the concept behind Konstrukt isn't always that easy to understand (I know, because I was a user of Konstrukt before I was a contributor). But when I understood how it all worked, I basically never wanted to do it any other way.
    The thing that has helped me a lot when learning Konstrukt's way of work is the reference to REST. When I started looking up articles on REST it hit me: every URL is a Resource and in Konstrukt, every Resource is a Component. It's really simple once you've got the hang of it.
    Yes, I blog, too.

  15. #40
    SitePoint Enthusiast
    Join Date
    Jul 2005
    Location
    Norway
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have been thinking about a different approach to mvc for web lately. Don't know if this idea is good or bad. I'll lay it out and then you can judge for yourselves.

    Key point:
    - When routing everything to one file you have to mess with the normal flow of a webapplication. You add a front-controller which with the help of a router implementation figure out which controllers to load. One also oftentimes add a .htaccess file for creating pretty urls. In other words, you add complexity. Is it neccessary?

    Alternate approach:
    - Folders determine structure (categories, modules etc)
    - When calling a controller action, one calls a file directly (/app/articles/edit.php) and in that file is the logic for that controller action
    - Each controller-file include optional parent files such as configuration, db-connection, template, authorization and module-specific pre-dispatch logic. These are usually grouped together into a single include-file which is included at the top of each controller-file
    - For each module in your app, you can create a different include file for your controller actions, so that you can have module-specific logic passed on to each controller-action in your module
    - Use autoloading for library-classes and model-classes

    A typical controller file:
    PHP Code:
    require 'core.inc.php';

    $form = new Form_EditArticle();

    if (!
    Request::isPost()) {
         
    $form->populate(Model_Articles::get(Request::get('id')));
    } else {
         if (
    $form->isValid(Request::post())) {
               
    Model_Articles::add($form->getValues());
               
    Response::redirect('index.php');
         }
    }

    require 
    VIEW_PATH 'articles/edit.php'
    View file:
    PHP Code:
    require TEMPLATE_PATH 'cms.php';

    head('Edit article');

    echo 
    $form;

    foot(); 
    Core.inc.php file:
    PHP Code:
    //Define path to view files
    define('VIEW_PATH''/usr/app/views/');

    //Define path to template files
    define('TEMPLATE_PATH''/usr/app/templates/');

    //Include autoloader for the library
    require realpath(dirname(__FILE__) . '/../../lib/autoloader.php');

    //Autoloader for forms
    //...

    //Autoloader for models
    //...

    //Authentication
    //....

    //Db connection etc... 
    Pros with this approach:
    - No need to mess with urls and translate them into something meaningful
    - Easy to see what's going on, and how things fit together.
    - No need for .htaccess
    - Unlimited categories/modules/subcategories
    - Easy to create actions/pages that needs to be different (like ajax responses, csv responses, upload script for images etc..)
    - Easy to move modules around.

    Cons:
    - Not suitable for cases where you have dynamic urls (like a website that get its content and structure from a database)
    - If you really don't want to have .php in your url.

  16. #41
    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 oeyvind View Post
    - If you really don't want to have .php in your url.
    You can save /app/articles/edit.php as /app/articles/edit/index.php to get around that problem.

    What you're describing is basically what Fowler calls a page controller (As opposed to a front controller). It has its merits, but it certainly has some limitations as you mention. The biggest benefit of it today, as far as I see it, is that it's the default modus for PHP, which means that you can expect almost anyone with prior PHP experience to understand it. That could have some value, especially in open source projects. And actually, that still seems to be the default for the popular open source PHP applications out there.

  17. #42
    SitePoint Wizard Young Twig's Avatar
    Join Date
    Dec 2003
    Location
    Albany, New York
    Posts
    1,355
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oeyvind View Post
    I have been thinking about a different approach to mvc for web lately. Don't know if this idea is good or bad. I'll lay it out and then you can judge for yourselves...
    I've done my fair share of this, and it definitely has its advantages and disadvantages. The simplicity is very nice, and it makes starting a new project take almost no time. Likewise, it makes for code that is very easy to follow.

    You do lose something by not piping all of your requests through one file, though. Manually including core.inc.php and your view files gets old quickly, for example. You also can't catch any uncaught exceptions in a central place and give an error message. Instead, your script will stop executing and either display an error or go silent (depending on display_errors, of course).

    There are really quite a few pros and cons to every setup. I've got to say, though, I'm starting to like this hierarchical idea.

  18. #43
    SitePoint Enthusiast
    Join Date
    Feb 2004
    Location
    Montreal
    Posts
    77
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    When I started a recent project, I wanted to get things up and running as quickly as possible and so this was almost exactly the approach that I took. However, instead of putting the controller stuff in the global level, I put action handler functions in the page controller file. The global include file ('core.inc.php' in your case) would determine which action function to call from the request uri and would look throughout the module path for a 'module.init.php' file that it would load as well as a similar, but global 'site.init.php'. This has worked pretty well so far, however, the major drawback has been the difficulty of internal redirects.

    Regardless, for smaller-scoped projects, I've found the approach to be very simple for rapid prototyping and even development.

    For the type of links discussed above, however, you will find that the page-controller approach is unrealistic. For example /blog/2009/03/ would necessitate a controller for each month of each year, all identical. Perhaps a simple .htaccess rule in the /blog/ subdirectory would suffice to remap the year and month as GET arguments. Anyway, I encourage you to try it out. At the minimum you will start with something that gets the job done and each iteration of functionality and refactoring that you add will improve your product. This is in contrast to trying to engineer everything in advance and never even starting the project itself (my problem).

  19. #44
    SitePoint Enthusiast
    Join Date
    Jul 2005
    Location
    Norway
    Posts
    88
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You also can't catch any uncaught exceptions in a central place and give an error message
    For exceptions one can use the set_exception_handler

  20. #45
    SitePoint Wizard Young Twig's Avatar
    Join Date
    Dec 2003
    Location
    Albany, New York
    Posts
    1,355
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by oeyvind View Post
    For exceptions one can use the set_exception_handler
    Fair enough. I've always preferred catching exceptions yourself to letting them go uncaught to an exception handler, but you're absolutely right.

    I guess this is one of the issues where I prefer the standard MVC/FrontController method. It strikes me as somehow cleaner, though I'll admit that may just be personal preference.

    There are limitations that aren't personal preferences, though. I promise.

  21. #46
    SitePoint Zealot
    Join Date
    May 2008
    Location
    Montreal
    Posts
    155
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I implement routes in a similar way to the majority of frameworks out there. I store all defined specific/generic/remapped routes in an object and use that same object to try to match the current URI against one of those routes. Here are some examples of how routes are stored:

    PHP Code:
    <?
    $routes
    ['/about'] = '/index/about';
    $routes['/(:year)/(:month)'] = '/archive/index/$1/$2';
    $routes['/(:year)/(:month)/(:day)'] = '/archive/index/$1/$2/$3';
    $routes['/(:year)/(:month)/(:day)/([a-zA-Z0-9-]*)'] = '/view/post/$4';
    The parser uses a few nifty tricks to match the longest route that it can. It ends up returning an array of what directory the file is located at, what the file name is, and then any other extra info. So, in essence, the structure of a route is:

    [/ the deepest directory found][/ file name][/ extra / variables /...]

  22. #47
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I wonder what is better for route testing - regexps or successive checks of individual parts?

  23. #48
    SitePoint Zealot
    Join Date
    May 2008
    Location
    Montreal
    Posts
    155
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Mastodont, I use both approaches.

    Each route that is added is split into two parts: everything up to, but excluding, the first generic part, for example: ( : year), and then everything that follows the start of the generic parts. This is the longest prefix of the route, and allows multiple routes of a common prefix to be grouped together (note: all routes without prefixes are also grouped together). Within these prefix groups, the variable part of the routes are sorted in descending order of their length, so that we try to match the remainder of the route against the longest regular expressions we can.

    Given a URI, U, split U into a queue, Q, of non-empty parts by the regular expression ~\s*/+\s*~. Let S be an empty string, representing our current longest prefix found so far.

    Code:
    While (Q is not empty) and (S+first(Q) exists as a longest prefix): 
        S := S+shift(Q).
    The result S is the longest prefix for the URI. We join the remaining parts in Q by a '/' and then iterate over the regular expressions and try to match the longest one.

  24. #49
    SitePoint Addict Mastodont's Avatar
    Join Date
    Mar 2007
    Location
    Czech Republic
    Posts
    375
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    How do you solve possible issue with different actions for various controllers? I.e. route
    :controller/:action/...
    We could have controllers articles, polls, news, each of them with different actions - this IMHO leads to more regexps ...

    I am trying now latter approach, split all routes and given URL, then subsequently eliminate routes which do not match.

  25. #50
    SitePoint Zealot
    Join Date
    May 2008
    Location
    Montreal
    Posts
    155
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Mastodont, this is either not solved using route re-mappings (i.e. the route parser just figures out the deepest that it can go to get a controller file, and accepts it), or it is solved using either generic or specific route re-mappings.

    For the most part, the route re-mappings have the following uses:
    - Limiting the number of arguments that get passed to the actions
    - Making an action appear to be a controller
    - Dealing with very variable routes, especially ones with common prefixes.

    Should it interest you, you may find the code to the route parser here: http://ioreader.com/code/php/route-parser.phps


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
  •