tags:

views:

155

answers:

5

I'm new to MVC and I'm trying to understand how MVC fits in to what I'm used to.

Let's say I have a simple static website with the pages: Home, About, Contact.

And let's say that I have one xhtml/css "template" which will be the view for the whole site. To keep it simple, in that tag I'll have a variable for the page contents.

So in the controller am I supposed to have an individual function for the 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 look, is the best practice to create a function for each different page?

But what if you have a site with 100 pages? Doesn't the controller get too big to manage?

But then again, if you had a single controller for each page, that also seems that it would be tough to manage?

I am beginning to understand how the MVC concept is helpful for database connection tasks as well as some CRUD as well. But I remain confused as how to think about "pages" in MVC.

Any advice is much appreciated. What's the best practice?

+1  A: 

You don't have to have a function for each page. a quick example I've found is:

<?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 Which is a PHP implementation of MVC (its seemed to me like you're working with PHP). You might want to have a look at their implementation etc. It was just the first one I found. Hope this helps.

dtroy
A: 

The controller in MVC tends to be the biggest part of your code base. So as far as worrying about it getting too big, that's to be expected.

However, when using MVC, you typically want the Model-View-Controller to be a 1 to 1 relationship. If you have an about page, you'll want a controller specifically for that view and the actions associated with what you can do on that page. The response may be to load another view, in which case another controller will respond to events to that. The model can be shared amongst the controller's, but you don't want any parts of your view to know anything about your model or it'll break MVC, the controller being the piece that functions as the glue.

If you are indeed doing something with PHP as dtroy mentioned, that'll probably help out. Unfortunately, I'm coming from experience with MVC on the iPhone. Same concept though all around.

In summary though: If you keep the controller responsible solely for the actions that can occur on a given view, like button clicks, etc... it should help keep your controller from getting too large and unwieldy.

Edit:

I forgot to mention, in response to your concern which I didn't address. To help with, for instance, "Controller Explosion", you may not necessarily want to create a controller for each page, but one for each type of view. For example, you may have a AboutViewController and a ContentViewController, and maybe a loginViewController. The AboutView and LoginView would be pretty unique, but if you can reuse your contentView. So if someone requested something about "Widgets", your content view would simply display information about widgets that it retrieved from your model, and display it in the appropriate location defined by your view. then when the user requests something about "gears", you can reuse the same ContentViewController to display different different information in the same fashion.

Gary
A: 

Basically you'll have a Page controller for your Page model. Then each page that you create will have a url like "/Pages/1", which will get routed to the "show" action of your Page controller.

MVC certainly takes a bit of getting used to, but once you get the hang of it, you'll really like it. Also check out resources on REST design, which will really help with problems like this.

When I design websites now, I think in terms of resources (models, more or less). So for instance, 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

This isn't for everyone (I don't want to turn this into a REST debate), but it helps me a lot, and I think it makes sense when you're dealing with things that are clearly objects like Pages.

Jon Smock
A: 

The controllers contain the empty functions if there are no actions on the page. You don't have to pass page content via controller.
Place all the content to 'view' component of current unit.

Frost
A: 

If you have a site with 100 pages, you would want most of your content to be stored in a database.

your URLs would be altered 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 would 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 need to have only one function which delivers all 100 of your pages. This would work if all your pages have a similar structure.

In other words, mvc works just like vanilla php... (but hopefully looks a bit cleaner)

Alterlife