Jump to content

Fully Understanding MVC Concept?


Liquid Fire

Recommended Posts

I have tried to fully understand the concept of MVC but don't get it, or see the usefulness of it.  Maybe it is because i come from a C++ background and heard of MVC till web development and I am used to programming a certian way.  What is the concept and point of the MVC pattern?  i think i understand the concept just don't see how it would be better/easier programming it.

 

This is my understanding of it from what i have read(based on something off ONLamp.com).  You have one controller (usually index.php).  From that controller you call the modal and event you want to do like index.php?modal=user&event=edit where the user is the modal and the edit si the view, correct me if i am wrong.  I just don't see how this would help me abd be better than have /user/edit.php or /project/edit.php becuase no matter what i need to code 2 different sets of code for for edit for user and another for project and if i am going to have to write 2 sets then i rather have them in seperate files.

 

if someone could explain why programming MVC is better than my way, it would be so helpful.

Link to comment
Share on other sites

This is probably not something thats going to be easily explained in one forum post, but I'm willing to give it a shot. Bear in mind, I'm not expert in the field myself.

 

The main objective of the MVC pattern is to separate logic from presentation. Your database interface is the Model, your application logic the Controller and your presentation the View.

 

You usually would have two controllers. The front controller which controls the overall application logic and calls another (module) controller more specific to the request. A simple example might be a website containing blog, contact, and gallery pages (modules).

 

front controller (index.php)

<?php

  $valid_actions('blog','contact','gallery');
  if (isset($_GET['module'])) {
    $module = $_GET['module'];
    // check the module is valid.
    if (in_array($module,$valid_actions)) {
      // include and instantiate module.
      include_once $module . '.controller.php';
      $obj = new $module();
      // check we have an action to perform and that it is callable.
      if (isset($_GET['action'])) {
        $action = $_GET['action'];
        if (is_callable(array($module,$action))) {
          // execute the action. (a method of the current module contoller)
          $obj->$action();
        }
      }
    }
  }

?>

 

You now need a blog controller (module). (blog.controller.php)

This was called directly by the front controller above.

<?php

  include_once 'blog.model.php';

  // this object was directly instatiated by the front controller.
  class blog {
    private $model = new blog_model();
    // if you passed a url like index.php?module=blog&action=index
    // to the front controller, this method would get called.
    public function index() {
      // call the blog model to fetch the latest 5 entries as an array.
      $blogs = $this->model->getlatest();
      // include the view.
      // this is all the end user sees.
      include 'blog.index.view.php';
    }
  }

?>

 

And a blog model. (blog.model.php)

This is called by the blog controller above.

<?php

  include_once 'database.class.php';

  // here is where most of the application specific (database) work is done.
  class blog_model {
    $db = new db();
    public function getlatest($amount=5) {
      // execute query and return an array.
    }
  }

?>

 

And finally, the view. (blog.index.view.php)

This is also called by the blog controller above.

<html>
  <head>
    <title>My Blog</title>
  </head>
  <body>
    <?php foreach ($blogs as $blog): ?>
    <p><?php echo $blog['title']; ?></p>
    <p><?php echo $blog['blog']; ?></p>
    <?php endforeach; ?>
    <hr />
  </body>
</html>

 

Now, if you wanted an rss feed of your latest blog entries, all you would need to do would be to add another method to the blog controller.

<?php

  public function rss() {
    $blogs = $this->model->getlatest();
    include 'blog.rss.view.php';
  }

?>

 

And create the blog.rss.view.php file.

<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>My Blog</title>
    <?php foreach ($blogs as $blog): ?>
    <item>
      <title><?php echo $blog['title']; ?></title>
      <blog><?php echo $blog['blog']; ?></blog>
    </item>
    <?php endforeach; ?>
  </channel>
</rss>

 

This would then be displayed when passed a url like index?module=blog&action=rss

 

Notice how easy it was to add the rss? Because most of (if not all) the logic was already taken care of. Your logic was in no way mixed with the presentation.

 

As you can (hopefully) see, once the model is built, its allot easier to add new presentation to your data. You'll also find that allot of the time your models (and even your controllers) can often be easily reused from project to project. They almost become simple plug-ins.

 

As I said, I'm no expert, and some might argue some points of my example. There can be allot more to it than what I tried to simply describe. Its pretty hard to describe in a simple example. If you genuinely want to know more about the benefits of MVC I would suggest downloading one of the already established frameworks and reading through the manuals doing some examples.

 

Eventually you just get it.

Link to comment
Share on other sites

You have one controller (usually index.php).  From that controller you call the modal and event you want to do like index.php?modal=user&event=edit where the user is the modal and the edit si the view, correct me if i am wrong.  I just don't see how this would help me abd be better than have /user/edit.php or /project/edit.php becuase no matter what i need to code 2 different sets of code for for edit for user and another for project and if i am going to have to write 2 sets then i rather have them in seperate files.

 

One of the benefits of the MVC is clearly illustrated by thorpe's example (easy implementation of the different representations of the same internal state).

 

The benefits of separation imposed by the MVC have a wider impact though. Without it, you can easily scatter similar logic across server pages. For example, using the traditional PHP approach, a Page Controller, you will have to repeat some of the same control an presentation logic on every entry point. No 1. weapon against repetition is abstraction. The general point of the MVC is to start abstraction at the highest level possible. Should you work the other way around, if you keep abstracting you will eventually end up with something that is similar, or should be similar, to an implementation of the MVC.

 

A common alternative to tackle repeating logic using the Page controller approach (however ineffective) is to use includes to manage recurring blocks of logic. In a relatively complex system you can easily litter you pages pages with includes though, all of which have to managed. If this sound familiar, you know this quickly becomes a pain in the ass. You can just manage 4 includes across 10 entry points, imagine 10 includes across 20 pages. Feel like managing 200 includes?

 

If you don't see the point of abstraction or reducing repeating logic in general, I suggest we move this discussion to focus on that first.

 

Link to comment
Share on other sites

Ok, so the point is to seperate the logic from presentation.  I think the current way i am thinking does this.  for example I have a news class.  the new cl;ass would have methods like:

 

get_news

print_news

 

Now get_news queries the database and returns me all the new is a multi-dim array.  print_news call get_news and then processes the data returned.  This means if i wanted a rss feed all i would have to do is add method called rss_feed_news.

 

The framework i am building is going to be like this.  Most classes will not have presentation logic on the class but the ones that does will follow this same patttern, a method to get the data and then methods to process the data.  Is this MVC?

Link to comment
Share on other sites

Ok, so the point is to seperate the logic from presentation.

 

No, the point is to separate presentation/presentation logic, business logic (domain and data/integration layer logic) and control logic form eachother.

 

The framework i am building is going to be like this.  Most classes will not have presentation logic on the class but the ones that does will follow this same patttern, a method to get the data and then methods to process the data.  Is this MVC?

 

No. Using separate methods for presentation logic can hardly be called abstraction. Your News class has at least one too many responsibilities: creating a visual representation of News. A better approach would be to have a View Helper that takes an object of type News and handles the presentation. That way you can have your presentation logic centered in your View package, facilitating polymorhpism (different suptypes of News can be handled by the same View Helper) and when you make a general change you don't have to traverse all your Domain classes (i.e. News) to mend the print_* methods.

Link to comment
Share on other sites

I don't see how having a View Helper class would help me much, it would just be taking the print_* methods out of the news class and putting them somewhere else but still have the same amount of code.  Maybe the news class is a bad example of the usefulness of it.

 

It's not about writing LESS code, at least not initially. In fact you'll probably write a lot of EXTRA code at first. It's about writing reusable, maintainable and extensible code. This has not exclusively to do with the MVC though...

Link to comment
Share on other sites

I don't see how having a View Helper class would help me much, it would just be taking the print_* methods out of the news class and putting them somewhere else but still have the same amount of code.  Maybe the news class is a bad example of the usefulness of it.

 

It's not about writing LESS code, at least not initially. In fact you'll probably write a lot of EXTRA code at first. It's about writing reusable, maintainable and extensible code. This has not exclusively to do with the MVC though...

 

well you were talking about how writing the helper class would allow classes the extend from news would be able to use that same class/method to display the data since it does have all the same things.  However chances are that those classes the extend from news will have extra data to be displayed(otherwise it was just a a news objects) and that mean i would be to write a different method(s) and a different class to display that extra data.  I guess i don't understand this because everything that i have read does not give good coding examples.  They give example that do what they are explaining but when i look at it i could write the same thing is a lot less code and they don't do a good jbo at explaining it IN CODE very well.  You could talk to me about patterns all day long and i would not learn very much unless you give me a code example that makes sense.  does anyone know any good coding example to explian this or a link to one?

Link to comment
Share on other sites

You're asking a lot, especially because you haven't really made clear what you need to learn. I can think of a couple of things you seem to be missing, but I honestly don't really know where to start. The things I know I've learned from reading books, and trying to apply whatever described, fortunately with success in most cases. I can't make this thread nearly as educative as 10 books by experts and practice, but I'll make an attempt at a comprehensive example as soon as I find the time.

Link to comment
Share on other sites

Have a look at CodeIgnitor which is a framework that gives you a MVC pattern to use. I know you didn't ask for this but using this framework really helped me to understand what the mvc is and how to use it. The separation of the three parts (Model, View & Controller) is really useful but I have also found that the model and controller can be blurred together quite easily but it is extremely useful to keep the view separate. If you haven't kept the view separate you will sooner or later come across a situation where some logic you are executing requires some setting to be made that you have past the point of doing. Say a script tag in the head section but you have already processed that part and can't put it there now. With an mvc all the logic for the page has been done before you start outputting the page itself so things like this become easier.

 

There are many ways of implementing this pattern and purists would say that you must have all three elements to call it mvc. I say that you have the general idea if you are separating the view. In my case I have controllers for a member and another one for games (flash game site). The game controller also acts as the model but the member has a separate model file to handle logic so I have blurred the separation with the game controller/model but kept the separation for the member. Why? complexity of what I am doing in both cases. The game controller only has three entry points and just does some simple database queries so I haven't created a model for that and do it in the controller. The member functionality is larger and is more than just querying the db so I have created a model to accompany it.

 

Hope this helps in some way.

Link to comment
Share on other sites

Thorpe's post has helped me a lot with understanding MVC.  I built a small app in Code Ignitor last night and it helped some too, just I am learning PHP and I don't like to take shortcuts right now like using frameworks...I'd rather code the whole thing myself so I learn more.

 

Would I be right in thinking that you would build a user module to handle user login etc (index.php?module=user&action=login) then would do checking within the front controller to see whether the user is authorised to view that page they are trying to access?  Or would you move that back on to those xxx.controller.php files? Also, is it acceptable to put things like "if($user_authorised){ display admin panel}" into the view?  Does that count as display logic?

 

Thanks,

Jacob

 

 

 

 

 

Link to comment
Share on other sites

There are other ways of handling authorization, but they can get quite complex. There is such a pattern as the intercepting filter that is specifically designed to apply a set of rules (filters) to a request. This seems to be a common way of handling authorization amongst these frameworks. Like I said though, It can get a little complicated.

 

If you where going to hard code your authorization in, the best place would be the action controllers, not the front controller.

 

As for your if ($user_authorised) question. I can't really see how a little logic in the view can be avioded.

Link to comment
Share on other sites

As for your if ($user_authorised) question. I can't really see how a little logic in the view can be avioded.

 

that to me would still be classed as presentation logic - ie, not making calcs or grabbing info from the DB, but deciding what/what not to display based on variables - like you would when making alternating row colours, for example - so all good there IMO.

Link to comment
Share on other sites

Thanks for this post, I think I'm getting the idea of MVC now.

 

However, I've tried implementing thorpe's code but it doesn't seem to work. I get an "unexpected T_NEW" error with the line from the controller:

private $model = new blog_model();

Removing the 'private' (does PHP have public/private methods? I didn't think it did) gives me an "unexpected T_VARIABLE, expecting T_FUNCTION" error.

 

Any ideas? (NB I haven't used the code 100% straight, I filled in the few missing bits.)

Link to comment
Share on other sites

Wait, is it because the new blog_model initialisation is not inside a function, eg constructor? I thought you could declare variables in classes outside of functions?

EDIT: okay looks like only constants can be declared outside of functions, everything else should be a constructor. Think I've got it working now :)

Link to comment
Share on other sites

Worked on this a little more; now I'm confused again ;) How would this work with, for example, a single blog post? Like the 'permalink' feature in most blogs?

 

You'd want a URL like index.php?module=blog&postid=123 and in the db you'd fetch the record with this id and display the whole post. We can't call $obj->$action(); anymore. I can't see how to do this with the current system without making "non-generic" changes to index.php, like "if we want to view a full post, we need to check for an extra variable".

Link to comment
Share on other sites

All the front controller need do is decide which class->method to call, once that is called its up to the method itself to get the variables it needs from the url. This would respond to a url like... index.php?module=blog&action=view&postid=123

 

<?php

class blog {
    private $model;
    public function __construct() {
      $this->model = new blog_model();
    }
    public function index() {
      $blogs = $this->model->getlatest();
      include 'blog.index.view.php';
    }
    public function view() {
      if (isset($_GET['postid'])) {
        $blog = $this->model->getblogbyid($_GET['postid']);
        include 'blog.view.view.php';
      }
    }
  }
?>

 

Of course there are much better ways of doing this (all my request data is packed into a request object for instance, long before the front controller even decides which action to call upon), but as a simple example this will work. As Iv'e said though, if you want to get into the details, download one of the better known frameworks and follow allong with there manuals. It will give you allot of ideas, even if you end up rolling your own.

Link to comment
Share on other sites

  • 2 weeks later...

There are other ways of handling authorization, but they can get quite complex. There is such a pattern as the intercepting filter that is specifically designed to apply a set of rules (filters) to a request. This seems to be a common way of handling authorization amongst these frameworks. Like I said though, It can get a little complicated.

 

If you where going to hard code your authorization in, the best place would be the action controllers, not the front controller.

 

As for your if ($user_authorised) question. I can't really see how a little logic in the view can be avioded.

 

Consider that there are two phases of access control:  user authorization and authentication.

 

First, user authentication, determines solely if the user is a user on the system.

 

User authorization is typically a group based approach, where the user's membership to certain groups either provides, or restricts his abilities.

 

In a small scale website, this might simply be used to determine if the user has access to a page, or area of the site.

 

In more complex models, it would be used to determine if the user has Read, Write or Delete access to an object such as a page, or a calendar, or a calendar event.

 

Some say this code should not be in the controller.  It should be in a "business logic" class, so it could be used from multiple "clients" such as web, wap, API, Ajax, etc.

 

However, an approach I recently took on my personal application (RocketCMS) was to integrate the controllers to the ajax server code so that I didnt need to create 'business logic' classes.    Now, my controllers can serve two masters, AJAX and direct through the framework.

 

MVC (or MVC+ as this is an extension of MVC) really is an ideal way to separate your application into tiers.  I personally abhor applications that mix SQL, HTML, PHP all in one bowl of spaghetti.  This is horrible coding and makes it very painful to work on any of those layers.  Although an application might work fine, and is used by thousands or millions etc, it doesnt make it easy on the programmer to maintain or modify the code.

 

Just my 2 cents.

 

Mark

 

Link to comment
Share on other sites

Ok, i think i may understand it a little better.  would this be an example of MVc:

 

index.php

<?php
$model_name = $_GET['model'] . "_model";

$model = new $model_name();

$model->$_GET['view']();
exit();
?>

 

admin_model.class.php

<?php
class admin_modal
{
    public function __construct()
    {
        
    }

    public function home_data()
    {
        //processed data to display home page
    }

    public function home()
    {
        $data = $this->home_data();

//code to display admin home info
    }
}
?>

 

so that index.php?model=admin&view=home how load up the admin home page.  Now some of the examples i have seem would have me include a file inside the home() method that would have the display data in it but to me, that does not provide anything except me using classes is a bad way(i feel including a file inside a class function is kinda bad).  So if i needed to add a rss feed I could make a method called home_rss() and use the home_data() and then just write the new code for the rss feed.  Is this not a good way to do MVC?

Link to comment
Share on other sites

  • 3 months later...

This is probably not something thats going to be easily explained in one forum post, but I'm willing to give it a shot. Bear in mind, I'm not expert in the field myself.

 

I tried your code bu when I run it, it gives an exception:

 

Parse error: syntax error, unexpected T_NEW in blog.controller.php on line 7

 

 

 

Link to comment
Share on other sites

  • 3 weeks later...

i saw a lot of external examples calling the vars like this ( echo $name; ) in the view file. But as you explained , they come in array style. how they pass  the array variable to a single variable ?

 

you did something like this in your example  ( view file )

 

<?php echo array['name']; ?>

 

that i can understand but there is a lot of examples in another tutorials dealing with <?php echo $name; ?>

 

how is that possible ?

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.