Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load Model into a controller in MVC

I am working on building a lightweight MVC, mainly for the learning process but I would like it to be good enough to use eventually.

Below is a basic example/demo of how a basic controller might would look, let's assume the URI has been processed and routed to this controller and these 2 methods.

1) I need to get data from database/cache/etc... inside my Model classes, I just need help on how I should load my models into my example controller below, you can see that I have added this below $profileData = $this->model->getProfile($userId) that is just made up and does not exist's, how could I get something like that to work though? Or should I load the model into the class a different way?

2) A lot of pages will require a user to be logged into the site. SHould I process that part below in the controller to check if a user is logged in, example, before building the profile page, check if user is logged in, if not then build a login page instead and add these checks inside of each controller method/page?

/**
 * Example Controller
 */
class User_Controller extends Core_Controller {

    // domain.com/user/id-53463463
    function profile($userId)
    {
        //GET data from a Model
        $profileData = $this->model->getProfile($userId);

        $this->view->load('userProfile', $profileData);
    }

    // domain.com/user/friends/
    function friends()
    {
        //GET data from a Model
        $friendsData = $this->model->getFriendlist();

        $this->view->load('userFriends', $friendsData);
    }
}

core

abstract class Core_Controller {
    protected $view;
    protected $model;

    function __construct(DependencyContainer $dependencyContainer){
        $this->view = new Core_View();
        //$this->view = $dependencyContainer->get(view);


    }
}
like image 263
JasonDavis Avatar asked Nov 04 '22 14:11

JasonDavis


1 Answers

There are probably tons of ways to accomplish what you are trying.

The "easiest" is probably to just override the constructor and instantiate the model directly.

in User_Controller:

public function __construct(DependencyContainer $dc) {
    parent::__construct($dc);

    $this->model = new User_Model();
}

I'm guessing that you are looking for something a little more automated though. If you want the Model to have the same name as the controller minus "_Controller", just use get_class($this) in the constructor and use PHP's string functions to parse out what you want. Once you have that in a variable, you can use that variable to instantiate the model:

in Core_Controller:

public function __construct(DependencyContainer $dc) {
    $this->view = new Core_View();

    // $model_class should be 'User_Model' now
    $model_class = str_replace('_Controller', '_Model', get_class($this));

    // now instantiate the model
    $this->model = new $model_class();
}

I haven't actually worked with any framework that can only have one model associated with each controller (except may CakePHP? I can't remember). With Symfony, the models and controllers are completely decoupled so you can use any model with any controller. You just instantiate the model as need. Symfony use the Doctrine ORM so for example, in a controller action, if you needed a model you would do something like this:

$model = Doctrine::getTable('User');

It might be worthwhile to consider a design more like that in order to promote a decoupled design and I promise that you will want more than one model in some controller at some point.

2.) As far as authentication. Something that seems to be fairly common is to have some sort of setting (whether in a config file or a member variable) that says whether or not the current action needs the user to be authenticated. This is processed each time the action runs (Yii calls these kinds of things filters). If the user needs to be logged in, it stores the page that they are trying to access, and then redirects them to a log in page (you should only ever have to create one). Once they properly authenticate, it will redirect them back to where they were originally heading.

like image 93
gregghz Avatar answered Nov 15 '22 05:11

gregghz