Setup HMVC with Codeigniter 3

Introduction

This is an example on HMVC Codeigniter 3. HMVC stands for Hierarchical Model View Controller. Modular Extensions make the Codeigniter PHP framework modular. Modules are groups of independent components, typically model, controller and view, arranged in an application modules sub-directory that can be dropped into other Codeigniter applications. This allows easy distribution of independent components (MVC) in a single directory across other CodeIgniter applications.

You can also use HMVC with Codeigniter 2. Please read here https://www.roytuts.com/setup-hmvc-with-codeigniter-2-1-4/

Prerequisites

Codeigniter 3.0.6 3.1.10, PHP 7.0.15

Example with Source Code

Here we will see how to configure HMVC modules with an example. The HMVC modules along with the full source code for the application can be downloaded from the link given at the bottom of the tutorial.

Configuring HMVC Modules

Open <project root directory>/application/config.php and update as follows:

/*
  |--------------------------------------------------------------------------
  | HMVC Modular
  |--------------------------------------------------------------------------
  |
  | Modules location
 */
$config['modules_locations'] = array(
    APPPATH . 'modules/' => '../modules/',
);

Create a new folder called modules under <project root directory>/application, where you will create your HMVC modules for the project.

Open application/config/autoload.php file and add below code snippets to it.

$autoload['helper'] = array('url', 'form');

HMVC in Action

Now if you want to use module specific configurations then you can put those config, routes etc. under each module’s config folder. Similarly you need to put module specific controller, model, view under each module’s controllers, models and views folders respectively.

The following figure shows two modules – signin and site with their respective directory structures.

codeigniter 3 hmvc

Creating Base Controller

We will create base controller class and we will extend this class from our each module’s controller class.

Create MY_Controller under <project root directory>/application/core directory:

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/* load the MX_Router class */
require APPPATH . "third_party/MX/Controller.php";

/**
 * Description of my_controller
 *
 * @author Administrator
 */
class MY_Controller extends MX_Controller {

    function __construct() {
        parent::__construct();
        if (version_compare(CI_VERSION, '2.1.0', '<')) {
            $this->load->library('security');
        }
    }

}

/* End of file MY_Controller.php */
/* Location: ./application/core/MY_Controller.php */

The above controller class extends MX_Controller class, which is an extension of the HMVC library. You will find HMVC libraries in the source code at the bottom.

Site Module

Create site directory under modules folder. Create config, controllers, models, views folders under site directory.

codeigniter 3 hmvc

Create a controller class Site in site.php file under <project root directory>/application/modules/site/controllers with below source code:

<?php

(defined('BASEPATH')) OR exit('No direct script access allowed');

/**
 * Description of site
 *
 * @author https://www.roytuts.com
 */
class Site extends MY_Controller {

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

    function index() {
        $this->load->view('home');
    }

}

/* End of file Site.php */
/* Location: ./application/modules/site/controllers/site.php */

Notice the above controller class extends our base controller MY_Controller class instead of CI_Controller class.

Create a view file called home.php under modules/site/views with below source code:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title>Welcome to CodeIgniter</title>

        <style type="text/css">

            ::selection { background-color: #E13300; color: white; }
            ::-moz-selection { background-color: #E13300; color: white; }

            body {
                background-color: #fff;
                margin: 40px;
                font: 13px/20px normal Helvetica, Arial, sans-serif;
                color: #4F5155;
            }

            a {
                color: #003399;
                background-color: transparent;
                font-weight: normal;
            }

            h1 {
                color: #444;
                background-color: transparent;
                border-bottom: 1px solid #D0D0D0;
                font-size: 19px;
                font-weight: normal;
                margin: 0 0 14px 0;
                padding: 14px 15px 10px 15px;
            }

            code {
                font-family: Consolas, Monaco, Courier New, Courier, monospace;
                font-size: 12px;
                background-color: #f9f9f9;
                border: 1px solid #D0D0D0;
                color: #002166;
                display: block;
                margin: 14px 0 14px 0;
                padding: 12px 10px 12px 10px;
            }

            #body {
                margin: 0 15px 0 15px;
            }

            p.footer {
                text-align: right;
                font-size: 11px;
                border-top: 1px solid #D0D0D0;
                line-height: 32px;
                padding: 0 10px 0 10px;
                margin: 20px 0 0 0;
            }

            #container {
                margin: 10px;
                border: 1px solid #D0D0D0;
                box-shadow: 0 0 8px #D0D0D0;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <h1>Welcome to CodeIgniter 3 HMVC</h1>

            <div id="body">
                <p>HMVC setup example with Codeigniter 3.1.10</p>
                
                <p>
                    <?php echo anchor('signin', 'Signin', 'title="Signin Here"'); ?>
                </p>
            </div>
            
            <p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo (ENVIRONMENT === 'development') ? 'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p>
        </div>

    </body>
</html>

Signin Module

Create signin directory under modules folder. Create config, controllers, models, views folders under signin directory.

codeigniter 3 hmvc

Create a controller class Signin in signin.php file under <project root directory>/application/modules/signin/controllers with below source code:

<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

/**
 * Description of signin
 *
 * @author https://www.roytuts.com
 */
class Signin extends MY_Controller {

    function __construct() {
        parent::__construct();
        $this->load->library('form_validation');
    }

    function index() {
        $data['title'] = 'Signin';

        $this->form_validation->set_rules('username', 'Username', 'required');
        $this->form_validation->set_rules('password', 'Password', 'required');

        if ($this->form_validation->run() === FALSE) {
            $this->load->view('signin', $data);
        } else {
            redirect();
        }
    }

}

/* End of file signin.php */
/* Location: ./application/modules/signin/controllers/signin.php */

Create a view file called signin.php under <project root directory>/application/modules/signin/views with below source code:

<?php
defined('BASEPATH') OR exit('No direct script access allowed');
?><!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <title><?php echo $title; ?></title>

        <style type="text/css">

            ::selection { background-color: #E13300; color: white; }
            ::-moz-selection { background-color: #E13300; color: white; }

            body {
                background-color: #fff;
                margin: 40px;
                font: 13px/20px normal Helvetica, Arial, sans-serif;
                color: #4F5155;
            }

            a {
                color: #003399;
                background-color: transparent;
                font-weight: normal;
            }

            h1 {
                color: #444;
                background-color: transparent;
                border-bottom: 1px solid #D0D0D0;
                font-size: 19px;
                font-weight: normal;
                margin: 0 0 14px 0;
                padding: 14px 15px 10px 15px;
            }

            code {
                font-family: Consolas, Monaco, Courier New, Courier, monospace;
                font-size: 12px;
                background-color: #f9f9f9;
                border: 1px solid #D0D0D0;
                color: #002166;
                display: block;
                margin: 14px 0 14px 0;
                padding: 12px 10px 12px 10px;
            }

            #body {
                margin: 0 15px 0 15px;
            }

            #container {
                margin: 10px;
                border: 1px solid #D0D0D0;
                box-shadow: 0 0 8px #D0D0D0;
            }
        </style>
    </head>
    <body>
        <div id="container">
            <h1>Signin Here!</h1>
            <div id="body">
				<?php echo validation_errors(); ?>
                <?php echo form_open('signin'); ?>
                <p>
                    <label for="title">Username</label>
                    <input type="input" name="username" /><br />
                </p>

                <p>
                    <label for="text">Password</label>
                    <input type="password" name="password" /><br />
                </p>
                <p>
                    <input type="submit" name="submit" value="Signin" />
                </p>
                <?php echo form_close(); ?>
				
				<p><?php echo anchor('site', 'Home', 'title="Go back Home"'); ?></p>
				
				<p class="footer">Page rendered in <strong>{elapsed_time}</strong> seconds. <?php echo (ENVIRONMENT === 'development') ? 'CodeIgniter Version <strong>' . CI_VERSION . '</strong>' : '' ?></p>
            </div>
        </div>
    </body>
</html>

Updating Route

Now change the default controller in application/config/routes.php file because site module is our welcome or home module:

$route['default_controller'] = 'site';

Testing the Application

Home Page

Signin Page

Source Code

You can download source code.

Thanks for reading.

Setup HMVC with Codeigniter 3

19 thoughts on “Setup HMVC with Codeigniter 3

      1. I would like to do HMVC with directories.
        Not Route []. If I make records and within the MVC triad (Customers, Users, pordutos). Create new directory with name and tools within it a new MVC (Config, etc, etc). But if you call the url mysite / registrations / customers, does not work.
        I want HMVC with MVC modules within each folder that is inside modules
        modules-> register [customers (MVC), Products (MVC)]
        modules-> Tools [Config (MVC), Rules (MVC)]
        Sorry my English is translated.

  1. Hi very good your tutorial, I suffered a little bit to understand that it was necessary to change the ‘MY_’ prefix for ‘MX_’ thank you.

  2. Hello,

    I have problem to use this example HMVC, my CI version custom based in constructor functions giving me problem to load.

    Thanks by your help!

  3. CodeIgniter HMVC object_to_array() error

    In application/third_party/MX/Loader.php you can do the following…

    Under public function view($view, $vars = array(), $return = FALSE) Look for… (Line 300)

    return $this->_ci_load(array(‘_ci_view’ => $view, ‘_ci_vars’ => $this->_ci_object_to_array($vars), ‘_ci_return’ => $return));

    Replace this with

    if (method_exists($this, ‘_ci_object_to_array’))
    {
    return $this->_ci_load(array(‘_ci_view’ => $view, ‘_ci_vars’ => $this->_ci_object_to_array($vars), ‘_ci_return’ => $return));
    } else {
    return $this->_ci_load(array(‘_ci_view’ => $view, ‘_ci_vars’ => $this->_ci_prepare_view_vars($vars), ‘_ci_return’ => $return));
    }

  4. Hey!..
    I am getting this error please help me to get out of this
    error msg-
    Message: strpos(): Non-string needles will be interpreted as strings in the future. Use an explicit chr() call to preserve the current behavior
    Filename: MX/Router.php
    Line Number: 239

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top