Extending HMVC modules in CodeIgniter Extending HMVC modules in CodeIgniter codeigniter codeigniter

Extending HMVC modules in CodeIgniter


Structure of the Modules

/modules    /core_crud        /controllers            /core_crud.php        /models        /views    /shop_curd        /controllers            /shop_crud.php        /models        /views

Code in core_crud.php

<?phpif (!defined('BASEPATH'))    exit('No direct script access allowed');class Core_crud extends MX_Controller{    function __construct()    {        parent::__construct();        $this->load->model('mdl_core_crud');    }    public function index()    {        // code goes here    }    public function mymethod($param1 = '', $param2 = '')    {        return 'Hello, I am called with paramaters' . $param1 . ' and ' . $param2;    }}

Code in shop_crud.php

<?phpif (!defined('BASEPATH'))    exit('No direct script access allowed');class Shop_crud extends MX_Controller{    public function __construct()    {        parent::__construct();        //$this->load->model('mdl_shop_curd');    }    public function testmethod()    {        // output directly        $this->load->controller('core_crud/mymethod', array('hello', 'world'));        // capture the output in variables        $myvar = $this->load->controller('core_crud/mymethod', array('hello', 'world'), TRUE);    }}

So instead of extending the whole module/controller I prefer just to call the method which is required. It is simple and easy too.

Note If module name and controller name are different then you have to pass the path

module_name/controller_name/mymethod

EDIT to support EXTENDS

File structure

File Structure

The code in core_crud.php.

if (!defined('BASEPATH'))    exit('No direct script access allowed');class Core_crud extends MX_Controller{    public function __construct()    {        parent::__construct();        $this->load->model('core_crud/mdl_core_crud');    }    public function index()    {        return 'index';    }    public function check_method($param1 = '')    {        return 'I am from controller core_crud. ' . $this->mdl_core_crud->hello_model() . ' Param is ' . $param1;    }}

The code in mdl_core_crud.php

if (!defined('BASEPATH'))    exit('No direct script access allowed');class mdl_core_crud extends CI_Model{    public function hello_model()    {        return 'I am from model mdl_core_crud.';    }}

The code in shop_crud.php.

if (!defined('BASEPATH'))    exit('No direct script access allowed');include_once APPPATH . '/modules/core_crud/controllers/core_crud.php';class Shop_crud extends Core_crud{    public function __construct()    {        parent::__construct();    }    public function index()    {        echo parent::check_method('Working.');    }}

Output :- I am from controller core_crud. I am from model mdl_core_crud. Param is Working.

Hope this helps. Thanks!!


If you are loading the models in the parent class or in the construct then it should be inherited in shop_crud. are you not looking to do class Shop_crud extends Core_crud {? is parent::__construct() not retaining the construct for you?

Is this something you can handle with routing to the same controller rather than extending a controller (wanting to inherit both the controller and the model seems strange to me or something you could handle with a route and a private function in the class to handle the logic)?


"Controllers" this name defines it's functionality. The controller is used to control a particular section. So in MVC framework I think it's better to create individual controller for individual module. But you can reuse the model i.e. you can call one model's function in another model. For this

First load your model like $this->load->model("modelName"); in your controllerThen call the function like $this->modelname->functionName();