Load view & model... where?

Hey all,

So im writing my own little mvc framework so I can better learn the mvc infrastructure and deepen my oop knowledge. anyhow…

As it stands right now, im calling my view and model classes from within my base controller, but I don’t think it should be called here, granted, it works fine, but I like to try to follow the best principles as I can. So, if I should not be calling them here, where/how should I be calling them?

I am also using a registry if that helps.

Base controller:


<?php

/**
 * Controller class
 * This is the Base Controller in which
 * all the others will extend from
 *
 * @abstract
 * @since 0.0.2
 */
abstract class Controller
{
    
    /**
     * Model Object
     * 
     * @var string
     * @access protected     
     */
    protected $_model;


    
    /**
     * View Object
     * 
     * @var string
     * @access protected     
     */
    protected $_view;




    /**
     * Constructor
     * 
     * @access public
     * @return void
     */
    public function __construct()
    {
        $this->_view = Registry::getObject('view');
    }




    /**
     * All controllers must contain an index method
     * 
     * @abstract
     * @return void
     */
    abstract function index();




    /**
     * Instantiate's our model
     * 
     * @access public
     * @param string $name Name of model
     * @return $_model object
     */
    public function model($name)
    {
        // All model class names must have a suffix of _Model
        $name = $name . '_Model';
        $this->_model = new $name();      
    }


}


/* End of file controller.php */
/* Location: ./system/core/controller.php */

Model:


<?php

/**
 * Model base class - extends Database
 *
 * @since 0.0.3
 */
class Model extends Database
{


    /**
     * Database Object
     * 
     * @access protected
     * @var string
     */
    protected $_db;


    
    public function __construct()
    {
        parent::__construct();


        $this->_db = Registry::getObject('db');
    }


}


/* End of file model.php */
/* Location: ./system/core/model.php */


Most frameworks that provide a model concept do have a function in the base controller that just creates an instance of a model class, sets it as a variable to the controller and it’s ready to go.

One thing I do question is how you set your model. The way you do it looks like you are not able to have more than one model on a controller. Every time you use the model function, it sets itself to a difference model instance. What if you needed to load 2 models in one controller action? I know that CodeIgniter for one sets any new model as a property of the controller by the model’s name.

If you’re already using a registry, isn’t it easier to request the model object from the registry as and when you need it? Or perhaps even a factory that churns out model objects? That way you can use different types of model with in the same controller. The registry would be responsible for instantiating new models or and storing those for later use. This also means you’re not creating a model object unless you need it and are actually going to use it.

Please note that I’m suggesting this not based on any type of academic knowledge of patterns and such, more out of experience :slight_smile:

what about this, I removed the view and model from the base controller into a load file, the controller then calls that.

now in my site controller, I can call them like:


        // Load our model
        $this->load->model('home');


        // Assign our data list from the db to our data array
        $data['results'] = $this->home->data_list();


        // Display our content page and footer
        $this->load->view('home/home', $data);


<?php


/**
 * Controller class
 * This is the Base Controller in which
 * all the others will extend from
 *
 * @abstract
 * @since 0.0.2
 */
abstract class Controller
{
    
    /**
     * Registry property
     *
     * @var string
     * @access protected     
     */
    protected $_registry;
    
    
    /**
     * Load property
     *
     * @var string
     * @access protected     
     */
    protected $load;




    /**
     * Constructor
     *
     * @access public
     * @return void
     */
    public function __construct()
    {
        // Get registry instance
        $this->_registry = Registry::singleton();
        
        // Load the load class
        $this->load = new Load($this->_registry);
    }




    /**
     * All controllers must contain an index method
     * 
     * @abstract
     * @return void
     */
    abstract public function index();


    
    /**
     * Magic get method
     * 
     * Get's the object from the registry
     * 
     * @final
     * @param type $key
     * @return object
     */
    final public function __get($key)
    {
        return $this->_registry->$key;
    }
}


/* End of file controller.php */
/* Location: ./system/controller.php */

mode;


<?php


/**
 * Model base class - extends Database
 *
 * @since 0.0.3
 */
class Model extends Database
{


    /**
     * Database Object
     * 
     * @access protected
     * @var string
     */
    protected $db;


    
    public function __construct()
    {
        parent::__construct();


        $this->db = new Database();
    }


}


/* End of file model.php */
/* Location: ./system/model.php */

return $this->_registry->$key;

this makes little sense to me as this suggest your storing a property in your registry not not an object or an array of objects? this comes the question why have a registry? or why not store them in a much more flexable way.

I’m using that so I can do this:


$this->load->model('home');

$this->home->data_list();

---- OR ----

$this->load->model('my_model');

$this->my_model->data_list();

If there is another option in doing this or doing it better, i’m all ears :slight_smile:

How about something like this?


$model = Model::getModel('home'); // perhaps ModelFactory?

If there’s already a usable $model, then it returns that. If not, it creates a new one, stores a reference and then passes the model back?

Database object should be Singleton. You can also set as :

Get Database object per type i.e. Master, Slave etc. This can be done by injecting config array



public function __construct()
    {
        parent::__construct();

        $this->db = DatabaseFactory::getInstance();
    }