Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly pass data from controller to view?

My current implementation:

class SomeController extends AppController
{
    function someaction()
    {   
        $d['text'] = "ahoy!";
        $this->render("someactionView", $d);
    }
}

And in AppController:

function render($file, $data = "")
{
    require "views/" . $file . ".php";
}

And the $data will be available in the views file. Is this a correct implementation? Are there any fallacies with this implementation?

like image 236
good_evening Avatar asked Sep 22 '13 23:09

good_evening


1 Answers

And the $data will be available in the views file. Is this a correct implementation? Are there any fallacies with this implementation?

Basically you do implement it like the most frameworks do. There's a couple of problems with that:

  • A controller takes an input and sends an output (which breaks the Single-Responsibility Principle)
  • A view is tightly coupled to HTML. Because of this, you cannot re-use the same view for another stuff, like XML, JSON.
  • If you do require "views/" . $file . ".php"; in render() method - you again tighly couple it. What if you change the location of views? Then you would have to slightly rewrite your method. This approach merely kills reuse-ability.

To refresh your basic knowledge:

Controller (also known as Editor)

Serves only singular purpose. It changes model state - that is, it should take an input that comes from $_POST, $_GET, $_FILES, $_COOKIE. In controller only variable assignment should be done and nothing more.

class Controller
{
   public function indexAction()
   {
        $this->view->setVar('age', $this->request->getPostParam('age'));
        $this->view->setVar('user', $this->request->getPostParam('user'));
        //...
   }
}

View

A view has a direct access to a model. In order to make make views more re-usable and maintainable you'd better pass required things as function parameters (or via setters)

class View
{
   public function render($templateFile, array $vars = array())
   {
      ob_start();
      extract($vars);
      require($templateFile);

      return ob_get_clean();
   }
}

How the view should be initialized and how the variables should be passed to it?

First of all - a view should be instantiated outside MVC-triad. Since a controller writes either to view or model - you'd pass variables to view via controller.

$model = new Model();
$view = new View($model);

$controller = new Controller($view);

// This will assign variables to view
$controller->indexAction();

echo $view->render();

Note : In real world scenario, a model isn't a class, but abstraction layer. I call it Model for demonstration purposes.

like image 118
Yang Avatar answered Oct 14 '22 18:10

Yang