MVC: Nested Views, and Controllers (for a website)
I'm about to do a PHP website using the MVC pattern. I am not using a framework as the site is fairly simple and I feel that this will give me a good opportunity to learn about the pattern directly. I have a couple questions.
Question 1: How should I organize my views? I'm thinking of having a Page view which will have the header and footer, and which will allow for a Content view to be nested between them.
Question 2: If I have 5 Content pages, should I make 5 different views that can be used as the content that is nested within the Page view? Or, should I make them all extend an abstract view called AbstractContent?
Question 3: What about controllers? I think there should be one main controller at least. But then where does the request go from there? To another controller? Or should I just call the Page view and leave it at that? I thought that controllers were supposed to handle input, possibly modify a model, and select a view. But what if one of the views nested within the view that a controller calls requires additional input to be parsed?
Question 4: Are controllers allowed to pass 开发者_开发百科parameters into the view? Or should the controller simply modify the model, which will then affect the view? Or is the model only for DB access and other such things?
1 - This is a matter of preference. The simplest way would be to have a separate header and footer file. Then you could do something like this in your page controller
$title="Page Title";
$var1 = 'var1';
$var2 = 'var2';
$var3 = array("asdf","adsfasdf","234");
include(HEADER); //$title is in header
include(DIR_VIEWS . 'page.php'); //$var1/2/3 are in page.php
include(FOOTER);
// variable were created before pages were included so they will be set in the templates
If you were to go the nested route you would have to start fiddling with str_replace and that starts heading towards a template engine, out of scope for this answer.
2 - No need to make views objects. A "view" can just be a file on your filesytem that contains the html for that view. Like my example above. These pages can contain basic php to loop/echo variables as well.
3 - You are describing a front controller (sometimes called dispatcher or router). This is really the way to go. There are a couple methods for creating a front controller.
You can have an array of urls that point to controllers.
$routes = array (
'~^/home/$~' => 'home.php',
'~^/contact/$~' => 'contact.php',
'~^/blog/.*?$~' => 'blog.php'
);
or you can use the first "directory" in the url as the controller name and load that file form your controller directory.
4 - The entire point of the controller is to get info from the model and pass the data to the view.
Edited for comment
If you want a bunch of views to have a sidebar you just include that view in the other view. For example:
<div id="content">
<p>lorem ispum stuff</p>
</div>
<?php include(DIR_VIEWS . 'sidebar.php');
Just make sure that in controllers that "control" pages with sidebars you include some code for sidebar functions:
if ( $_GET['keywords'] ) {
$sidebar_search_results = get_search_results($_GET['keywords']);
}
// this code should be in a file that you include
$sidebar_search_results
could be an array of results that your sidebar view parses and displays.
- Think about what ways you'd want your HTTP responses to look like: full pages with/without nav, stripped pages for printing, JSON & XML responses, an index/sitemap. After you feel the site is forming, add more and more shortcuts for getting your response out there with as little code as possible.
- If the page layout is similar, I would use the same view and load content into it from a model (possibly a database).
- Check out the Front Controller pattern: you should always be able to intersect the request in a single point of entry. I would put something hierarchally in front of your controllers and then have one controller per "main page" (forum, blog, news). This is sufficient to control, but you'd have to decide what chunks are large/small enough for you.
- Controllers are responsible for everything that gets passed into the views. Controllers should fetch data & settings & what-not from models and pass on to the views.
Question 1:
This is indeed a way to do this, and one which I allways use.
Question 2:
Just keep views as simple as possible. I tend to create just 5 separate views (plain php files).
Question 3:
In the normal mvc pattern, there is one front controller (which OS just a bootstrap file, the index.php) which executes one controller.
In HMVC, controllers can send additional request to other controllers.
Question 4:
The normal MVC pattern applies on normal apps, where views are persistent, and can observe the models. With web applications this is not possible, because every request everything is reloaded. So the most used pattern is to let the controller pass the parameters to the view.
精彩评论