Trying to understand MVC Application Archietecture
I am new to MVC and I am trying to understand how MVC approaches what I am used to.
Let's say I have a simple static website with pages: "Home", "About", "Contact".
And let's say I have one xhtml / css template that will represent the entire site. To keep it simple, in this tag I will have a variable for the page content.
So in the controller I have to have a separate function for content for each page ????
For example:.
function home()
{
$data['content'] = "<p>some html home page content</p>";
$this->load->view('myView', $data);
}
function about()
{
$data['content'] = "<p>some html about page content</p>";
$this->load->view('myView', $data);
}
So, while I know this is a super-simplified view, is it best to create a function for every other page?
But what if you have a website with 100 pages? Is the controller too controlled?
But then again, if you had one controller for each page, does this also seem like it would be difficult to manage?
I am starting to understand how the MVC concept is useful for database connection tasks as well as some CRUD. But I am still confused how to think about "pages" in MVC.
Any advice is greatly appreciated. What's the best practice?
You don't need to have a function for every page. a quick example I found:
<?php
//This is an example of a KISSMVC controller
//It is simply a function, which will be called by an URL such as:
//http://example.com/article/show/234
//TIP: Please assign default values to all parameters
function _show($articleid=0) {
//SECTION 1: INPUTS
//Filter, sanitize and store all inputs used by this controller
$articleid=min(0,(int)$articleid); //zero or positive integer
$uid = isset($_SESSION['authuid']) ? $_SESSION['authuid'] : 0;
$someconfig = $GLOBALS['registry']['someconfig'];
//SECTION 2: LOGIC
//Call functions/objects that implement your business logic with the inputs from SECTION 1
//Data returned from your Model should not contain UI specifics (such as html code)
$loggedinuser = new User();
$loggedinuser->retrieve($uid);
$article = new Article();
$article->retrieve($articleid);
//SECTION 3: PRESENTATION
//Call the view templates with the data obtained from SECTION 2
//A change in UI should only affect code in this section
//Sometimes there is no output needed, only a header redirect is returned
if (!$loggedinuser->hasPermission('view_article')) {
$vars['body']='<p class="error">You have no permission to access this page!</p>';
View::do_dump(APP_PATH.'views/mainlayout.php',$vars);
exit;
}
$vars['article']=$article;
//article template is defined in views/layout/view_article.php
$vars['body']=View::do_fetch('layouts/view_article.php',$vars);
View::do_dump(APP_PATH.'views/mainlayout.php',$vars);
}
Taken from http://kissmvc.com/php_mvc_framework/code What is PHP MVC implementation (I thought you were working with PHP). Maybe you should take a look at their implementation, etc. This was only the first one I found. Hope this helps.
source to share
The controller in MVC is usually the largest part of your code base. So if you worry about it getting too big, you can expect it.
However, when using MVC, it is usually required that the Model-View-Controller be a 1 to 1. If you have an about page, you need a controller specifically for that view and actions associated with what you can do on that page. The answer might be to load another view, in which case the other controller will respond to events on that. The model can be shared with the controller, but you don't want any part of your view to know anything about your model, or that will break MVC and the controller will be the part that works like glue.
If you are actually doing something with PHP as mentioned in dtroy this will probably help. Unfortunately I am coming from experience with MVC on iPhone. The same concept, albeit around.
In conclusion: If you hold the controller solely responsible for actions that may occur in a given view, such as button presses, etc., this should help your controller get too large and unwieldy.
Edit:
I forgot to mention in response to your concern, which I did not address. To help with "Controller Explosion" for example, you might not necessarily create a controller for each page, but one for each view type. For example, you might have AboutViewController and ContentViewController and possibly loginViewController. AboutView and LoginView would be pretty unique, but if you can reuse your content view. Therefore, if someone asked for something about "Widgets", your content view would simply display information about the widgets obtained from your model and display them in the appropriate location defined by your view. then when the user requests something about "transfers" you can reuse the same ContentViewController,to display various information in the same way.
source to share
Basically you will have a page controller for your page model. Then each page you create will have a URL like "/ Pages / 1" that will be redirected to the "show" action of your page controller.
MVC takes a bit of getting used to, of course, but once you get the hang of it, you'll really love it. Also check out REST design resources that will really help with problems like this.
When I create websites now, I think in terms of resources (models, more or less). So, for example, you will have many pages or users or questions or recipes or ... each of these things is a thing / model. I usually make a separate controller for each one and put 7 actions in that controller:
index - used to show a list of all the Pages (URL like "/Pages")
show - used to show an individual Page (URL like "/Pages/1")
new - used to show a form to create a new Page
edit - used to show an edit form for a Page
create - used to actually create the new Page from the new form
update - used to actually update the Page from the edit form
destroy - used to delete a Page
It's not for everyone (I don't want to turn this into a REST discussion), but it helps me a lot, and I think it makes sense when you're dealing with things that are clearly objects, such as Pages.
source to share
If you have a site with 100 pages, you want most of your content to be stored in a database.
your urls will be changed to look something like this:
http://yoursite.com/showpage?pageid=mvc
http://yoursite.com/showpage?pageid=home
http://yoursite.com/showpage?pageid=whatever
and your controller will look something like this:
function showpage()
{
$post = yourframework.getmodel('post').getPost($_GET['pageid']);
$data['title'] = "<p>" . $post.title . "</p>";
$data['content'] = "<p>" . $post.title . "</p>";
$this->load->view('myView', $data);
}
Not syntactically correct, but you get the idea. You should only have one function that provides all 100 of your pages. This will work if all of your pages have a similar structure.
In other words, mvc works just like vanilla php ... (but hopefully looks a little cleaner)
source to share