Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing data from MVC Controller to View in PHP

I have my own hand-rolled PHP MVC framework for some projects that I'm working on. When I first created the framework, it was in the context of building an admin CMS. Therefore, there was a very nice one-to-one relationship between model, view, and controller. You have a single row in the DB, which maps to a single model. The controller loads the model and passes it to the view to be rendered (such as into an edit form). Nice, clean, and easy.

However, now that I'm working on the front end of the site, things are getting sticky. A page isn't always a view of a single model. It might be a user directory listing with 20 users (each a User model). Furthermore, there might be metadata about the request, such as pagination (current page, total pages, number of results) and/or a search query.

My question is, what is the cleanest way to pass all this data to the view?

Some options I'm considering:

  • Have the controller create an array and pass that to the view as a single parameter:

    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc.
            $data = array()
            $data['models'] = $models; 
            $data['currentPage'] = $current;
            $data['totalPages'] = $total;
            return $view->render($data);
        }
    }
    
    class UserView{
        public function render($data){
            // render the data
        }
    }
    
  • Create properties in the view class and have the controller populate them:

    class UserView{
        public $models;
        public $currentPage;
        public $totalPages;
    }
    
    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc.
            $view = new UserView();
            $view->models = $models; 
            $view->currentPage = $current;
            $view->totalPages = $total;
            return $view->render();
        }
    }
    
  • Give the view some sort of generic HashMap or Collection object as a container which can hold any arbitrary number and name of data.

    class UserView{
        public $collection = new Collection(); // works like a Java collection
    }
    
    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc. 
            $view = new UserView();
            $view->collection->add($models,'models');
            $view->collection->add($currentPage,'currentPage');        
            return $view->render();
        }
    }
    

I know that technically any of the could work, but I'm unsure of the best choice, or if there's a better or more conventional choice that I'm missing.

like image 807
Warren Benedetto Avatar asked Jun 04 '09 05:06

Warren Benedetto


People also ask

How pass data from controller view in MVC in PHP?

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();

How can we pass the data from controller to view in MVC?

The other way of passing the data from Controller to View can be by passing an object of the model class to the View. Erase the code of ViewData and pass the object of model class in return view. Import the binding object of model class at the top of Index View and access the properties by @Model.

How do I pass ViewData to view?

To pass the strongly-typed data from Controller to View using ViewData, we have to make a model class then populate its properties with some data and then pass that data to ViewData dictionary as Value and selecting Key's name is the programmer's choice.


1 Answers

I'm going to recommend the concept of Fat Models, Skinny Controllers (or, Fat Models Thin Controllers if you prefer...)

In otherwords, your model is too strict - tying your model to represent only something like a RowDataGateway is extremely limiting.

In fact, I think good models hide the fact that you're reading the data from a database at all. Because, in reality, your data could be in text files, or from a web service, or whatever. If you treat your Model like nothing more than a glorified DBAL, you doom yourself to having tightly-coupled code in your controllers that just won't let you break away from the "data only comes from the database" way of thinking.

like image 105
Peter Bailey Avatar answered Sep 16 '22 14:09

Peter Bailey