$ this-> model = $ model; 意味着在MVC中

I am new to coding and I am learning about MVC.

Could you please explain this simple code?

model.php

<?php
class Model
{
    public $string;

    public function __construct()
    {
        $this->string = "MVC + PHP = Awesome!";
    }
}

View.php

<?php
class View
{
    private $model;
    private $controller;

    public function __construct($controller,$model)
    {
        $this->controller = $controller;
        $this->model = $model;
    }

    public function output()
    {
        return "<p>" . $this->model->string . "</p>";
    }
}

Controller.php

<?php
class Controller
{
    private $model;

    public function __construct($model)
    {
        $this->model = $model;
    }
}

Controllers are the transport layer of an MVC application. It means, that a controller retrieves the data from the request (HTTP or CLI), then it hands the data (if any) over to a class that knows about application's business logic which in its simplest form, is a model. Models do their logic and return their result to the controller. Then the controller hands over the data to a view file to represent it. So, in a nutshell:

  • Controller retrieves the data from a request.
  • Controller hands it over to a class that knows how to handle the business logic; A model class in its simplest form.
  • The model then does its job and returns the result. In most cases, models are representing an entity and holding its state. Usually a model action, manipulates the state. It knows nothing about either the controller or the view.
  • Controller hands over the results (usually the model state) to a view file.
  • View represents the results (the model state).

The so called "MVC frameworks" are built to provide developers with the tools needed for such orchestration. I strongly recommend you to look into such frameworks instead of writing your own.

MVC Paradigm Diagram

You'll see a lot of these diagrams around; They only make sense if you already know about how MVC works.

So, theoretically, we know that a controller needs to interact with one or more model classes as its dependencies. But how are we going to implement this? One way is to utilize class properties to hold an instance of the required models. So, the controller can access them as easily as a $this->model->whatever.

The other popular concept you need to know about is Dependency Injection. It's a design pattern, that does what the name states. In simple words, you inject class dependencies either through its constructor (known as constructor injection) or through its setter methods (known as setter injection). If utilized correctly, it makes the class loosely coupled from its dependencies, as they may be injected from the outside.

Now that you know about basic concepts of MVC and DI, let's have another look at your code:

<?php
class Controller
{
    // Designate a place to hold class dependencies
    private $model;

    // Accept a $model instance in the constructor, so the 
    // dependencies can be injected from the outside
    public function __construct($model)
    {
        // Set the dependency in a class property, so it's easily
        // accessible for later use of class methods.
        $this->model = $model;
    }
}
  • You take $model you've declared with private $model
  • Refer to it as $this->model because it is this particular object's variable, and it may take up a different value in each object instance
  • Assign it the value of $model you pass in your constructor when you instantiate the object

The example below demonstrates how $this->var = $var may work. We can see, that we pass 2 different Models to the View.

class Model
{
    public $string;

    public function __construct($string = NULL)
    {
        if(!empty($string)){
            $this->string = "DEFINIETLY AWESOME";
        } else {
            $this->string = "MVC + PHP = Awesome!";
        }
    }
}

class View
{
    private $model;
    private $controller;

    public function __construct($controller,$model)
    {
        $this->controller = $controller;
        $this->model = $model;
    }

    public function output()
    {
        return "<p>" . $this->model->string . "</p>";
    }
}

class Controller
{
    private $model;

    public function __construct($model)
    {
        $this->model = $model;
    }
}

$model = new Model(); 
$controller = new Controller($model); 
$view = new View($controller, $model); 
echo $view->output();
// MVC + PHP = Awesome!

$model = new Model("a"); 
$controller = new Controller($model); 
$view = new View($controller, $model); 
echo $view->output();
// DEFINIETLY AWESOME

However, from an MVC perspective: we shouldn't need to pass $controller to the View.

class Model
{
    public $text;
    public function __construct()
    {
        $this->text = 'Hello world!';
    }
}

class View
{
    private $model;
    public function __construct(Model $model)
    {
        $this->model = $model;
    }

    public function output()
    {
        return '<h1>' . $this->model->text .'</h1>';
    }
}

class Controller
{
    private $model;
    public function __construct(Model $model)
    {
        $this->model = $model;
    }
}

//initiate the triad
$model = new Model();
//It is important that the controller and the view share the model
$controller = new Controller($model);
$view = new View($model);
echo $view->output();