Jump to content

PHP MVC question.

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
6 replies to this topic

#1
bleastan

bleastan

    Learning Programmer

  • Members
  • PipPipPip
  • 40 posts
Hello peoples i got a question regarding a MVC pattern in PHP.

The last ive been experimenting with OOP and trying to construct a simple MVC thingy. ow basically i have all the 3 classes (model, view and controller). Now my question is: Where do i start the program? I my view class i got a function which shows a simple form on the screen. However i dont know how to call the function (or i do know how to call the function, i just dont know how to make it the first thing to execute). So when ppl enter www.awebsite.com/view.php it should execute that function.

I tried to do it with the constructor like this:
<?php

class View {

function __construct()
{
$this->showStartup();
}

//So what i want is that this function is the first thing that executes when the view.php is called //from the URL www.awebsite.com/view.php

public function showStartup();
{
//this function should print the forms.

}
}
?>

considering im still new with OOP im not sure if it is possible like this... If its not, then how should it be done cause i really dont know atm.

Thx in advance.

#2
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts
You don't execute the view directly. That is what the controller is for. Here is how I generally set up my MVC.

BlogModel.php
class BlogModel {

    function getPosts() {

        // mysql query

        // return array of blog posts

    }

}

BlogController.php
class BlogController {

    private $model;

    function __construct($view) {

        $this->model = new BlogModel();

        switch($view) {

            default:

                $this->index();

        }

    }


    private function index() {

        $blogs = $this->model->getPosts();

        include_once("views/BlogView.php");

    }

}


BlogView.php
foreach($blogs as $blog) {

    echo $blog . "<br />";

}


index.php
switch($_GET['module']) {

    case 'blog':

        new BlogController($_GET['view']);

        break;

    }

}

index.php acts as a front controller that creates "modules." Each module is composed of a model, view, and controller. The front controller invokes the controller for each module, and then the modules controller is responsible for displaying the view.

#3
bleastan

bleastan

    Learning Programmer

  • Members
  • PipPipPip
  • 40 posts

John said:

You don't execute the view directly. That is what the controller is for. Here is how I generally set up my MVC.

BlogModel.php
class BlogModel {

    function getPosts() {

        // mysql query

        // return array of blog posts

    }

}

BlogController.php
class BlogController {

    private $model;

    function __construct($view) {

        $this->model = new BlogModel();

        switch($view) {

            default:

                $this->index();

        }

    }


    private function index() {

        $blogs = $this->model->getPosts();

        include_once("views/BlogView.php");

    }

}


BlogView.php
foreach($blogs as $blog) {

    echo $blog . "<br />";

}


index.php
switch($_GET['module']) {

    case 'blog':

        new BlogController($_GET['view']);

        break;

    }

}

index.php acts as a front controller that creates "modules." Each module is composed of a model, view, and controller. The front controller invokes the controller for each module, and then the modules controller is responsible for displaying the view.

Ah thx that clears up some things however i still got a question :).

you have the
index.php
switch($_GET['module']) {

    case 'blog':

        new BlogController($_GET['view']);

        break;

    }

}

Now in this switch theres supposebly always a module but if theres no module nothing happens. Or am i just reading or you just left out the default. Anyhow wouldnt this be possible (or is this not correct use of the MVC pattern?
index.php
switch($_GET['module']) {

    case 'blog':

        new BlogController($_GET['view']);

        break;

   default:

       $view = new View();

       $view->showMainform();

    }

}

So basically when the user first enters on index.php it should execute the showMainform() function from the view class. And after that i want to use the controller and model.So After the form submit the field data are posted to the Controller who puts the data in an array and sends it to model to do some nifty things with it, who afterwards send the results to the viewclass who outputs the data to the screen. This is basically how i understood MVC or am i just plain wrong?

#4
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts
You're very close (and actually right for the most part, but you can be more right).

Quote

So basically when the user first enters on index.php it should execute the showMainform() function from the view class.
Technically you can do it this way since index.php is a controller, but it is a special kind of controller (it is called a front controller). I use the index.php to instantiate other (module) controllers and avoid calling any methods in index.php since it increases cohesion and coupling (things you want to avoid). So when the user first enters (the front controller) index.php it should instantiate a (module) controller. That (module) controller is then responsible for executing the view.

Quote

So After the form submit the field data are posted to the Controller who puts the data in an array and sends it to model to do some nifty things with it, who afterwards send the results to the viewclass who outputs the data to the screen.
Yes and no. This actually is a valid implementation, but I avoid having the model talk directly to the view (because once again, it increases cohesion and coupling). After the form submits, the data is posted to the controller. The controller sends that data to the model (by calling a method). The model does nifty things with it and returns it to the controller. The controller then takes that data and "sends" it back to the view. Ideally, your model doesn't know anything about the view or controller, and the view doesn't know anything about the model or controller. The controller does all the directing, and serves as a middle man between the model and view.

Also, my views are never objects. They only contain HTML, loops, and very few if/else and switch/case structures. All data should be manipulated by the model and all logic should be handled by the controller (with the exception of data specific logic which is handled by the model).

Lastly, if you ask 10 different people about their implementation of the MVC, you will probably get 10 different implementations. The one I described above, is the "best practices" method used my most frameworks, but the way the model, view, and controller communicate is a topic of heavy discussion with no "right" answer.

#5
bleastan

bleastan

    Learning Programmer

  • Members
  • PipPipPip
  • 40 posts
Ah thanks alot for this so what i need to do is (or not need to but.. is best practice as you say). Instead of calling a view directly from the model, the model send the data back to controller who afterwards send it to view?

Now that the subject is about MVC in general i got another question (yes im annoying :P). But i was thinking considering view can generate diffirent kinds of forms is it 'good' to make a diffirent controller for each form? I was talking to this with someone and he said that its better to just make one controller but i personally had the idea of making 1 main controller class with standard methods (like date validation and stuff, to validate date input fields) and then make subclasses (i kinda forgot the word, but with subclasses i mean classes that exted the main controller) for each form (so like a controller for each form). If i would do it like this would that be like 'violating' the principle of MVC? So to make it more clear i drew this awesome picture in mspaint to illustrate what i mean: Posted Image

I know MVC isnt a REQUIRED thing so i guess anything can work its just that im trying to do it the 'correct' way.

anyways thx already :)

#6
John

John

    Writes binary right handed and hex left handed

  • Moderators
  • 6,321 posts

bleastan said:

Ah thanks alot for this so what i need to do is (or not need to but.. is best practice as you say). Instead of calling a view directly from the model, the model send the data back to controller who afterwards send it to view?
Exactly.

bleastan said:

Now that the subject is about MVC in general i got another question (yes im annoying :P). But i was thinking considering view can generate diffirent kinds of forms is it 'good' to make a diffirent controller for each form? I was talking to this with someone and he said that its better to just make one controller but i personally had the idea of making 1 main controller class with standard methods (like date validation and stuff, to validate date input fields) and then make subclasses (i kinda forgot the word, but with subclasses i mean classes that exted the main controller) for each form (so like a controller for each form). If i would do it like this would that be like 'violating' the principle of MVC? So to make it more clear i drew this awesome picture in mspaint to illustrate what i mean: Posted Image

I know MVC isnt a REQUIRED thing so i guess anything can work its just that im trying to do it the 'correct' way.

anyways thx already :)

I have one controller per "module." In the MVC, a view is not suppose to generate other forms (this would actually be more like the MVVM [model, view, view-model] pattern which comes with a lot of criticisms). Each form is suppose to be its own view, and the controller is suppose to "generate" / display them. To give a concrete example, think of a Photo Gallery as a module. The photo gallery module will have three views: an Album view, a Gallery view, and a Picture view. The album view simply displays a table of galleries. The gallery view displays a table of pictures, and the picture view shows a single picture. The controller is suppose to select which view to "generate" or display. Make your views as simple as possible. Ideally, the only PHP you have in a view is to echo a variable. However, more times than not, that variable will be an array, so you will also need loops to "echo" that variable. And occasionally you will need if/elses. A typical view that uses all of these might look like this:

foreach($albums as $album) {
    if($album == "main")
        echo "<img src=\"$album\" border=\"1\" /><br />";
    else
        echo "<img src=\"$album\" border=\"1\" /><br />";
}

If you include() other files in your view, it is wrong. If you are doing something like if($_POST['foo'] == ""), it is wrong.

Your idea about inheritance (parent/child classes) is a good one. As you write multiple models, there will be code a lot of overlap that can be refactored into it's own class. However, whether that code should be an a "parent" class or a "helper" class is a completely different pattern (composition and helper respectively) and discussion. Most modern frameworks need/do both. That being said, you are putting the data validation in the wrong area. All data manipulation is suppose to be done by the model.

#7
bleastan

bleastan

    Learning Programmer

  • Members
  • PipPipPip
  • 40 posts
So thanks alot so far. So based on your feedback i kinda came up with the following Posted Image

I assume with 'module' u meant a combination of a model, view and a controller. So now i have it that the VIEW has 1 mainfunction generateLayout(). The only thing that function does is build up the tableframe to show the forms in. The forms themselves (with controlsl like radiobutton etc...) are inputted into that tabel with the functions of generateForm() in the childclass of View which. It also has the function generateOutput() which puts the results in the table.

I made two seperate controllers to handle the 2 forms. The only thing they do is get the $_POST variables and send them to MODEL. The checkSession() in Controller just checks if the user is logged in.

The model now has all the validation things, like validateDates(), validateValues() and checkFunction(). checkFunction checks what function needs to be executed and Wherefrom (so if it needs to fetch data from the database it uses DatabaseModel, if it needs to get data from a .csv it uses the CsvModel. After the data retrieval etc.. the Controller sends the fetched data to the VIEW who executes generateOutput() to show the output on the screen. So the view handles the generatig of layout and output, Controller just gets data from forms and model does all the work.This is basically how i think it should be but i got (once again) a question :).

I only have 2 forms now, but what if i add 10 more forms. Then i would also need 10 more controllers but wouldnt there be too many classes then which makes everything a bit... messy? Or is it wrong to make so many controllers and i should handle it in another way?