CodeIgniter 4 HMVC applications are built using the HMVC Architecture Pattern, which allows for greater modularity and flexibility. This architecture, based on the traditional MVC pattern, enables the development of independent modules, each containing its own Model, View, and Controller components. This modular structure simplifies maintenance and encourages code reuse across different parts of the application.

Codeigniter 4 HMVC Application -  Implementing the HMVC Architecture Pattern

Table Of Content

1 Prerequisites

1.) PHP version of 8.2
2.) MySql

2 Introduction

In this article, we explore the CodeIgniter 4 HMVC application in detail. We’ll walk through how to set up HMVC integration in CodeIgniter 4, and look at examples of applications built using the CodeIgniter 4 HMVC Architecture Pattern.

3 Create / Install a Codeigniter 4 Project

3.1 Install Codeigniter 4 Project

To get started, ensure that you have Composer installed on your computer. Use the following command to install a new CodeIgniter project:

composer create-project codeigniter4/appstarter ci-4-hmvc-app

Then, navigate to your project directory:

cd ci-4-hmvc-app

3.2 Configure MySql Database

After successful installation, configure your database by modifying the .env file. Input your database credentials as shown below:

database.default.hostname = localhost
database.default.database = codeigniter_4
database.default.username = root
database.default.password = 
database.default.DBDriver = MySQLi
database.default.DBPrefix =
database.default.port = 3306

4 HMVC Module Setup

To set up HMVC integration in CodeIgniter 4, create a new directory called Modules under the app folder. For instance, you can create a module named Blog, containing controllers, models, and views subdirectories.

5  Register your custom namespace

Next, register the namespace for the Modules/Blog in app/Config/Autoload.php by adding the following to the psr4 array:

<?php
namespace Config;
use CodeIgniter\Config\AutoloadConfig;
class Autoload extends AutoloadConfig
{
    // ...
    public $psr4 = [
        APP_NAMESPACE => APPPATH,
        'Modules\Blog'   => ROOTPATH . 'Modules/Blog',
    ];

    // ...
}

6 Create Migration and Model

Create a migration for the posts table to store your data. Also, create a model PostModel. Run this command to generate the model:

php spark make:model PostModel --suffix --namespace "Modules\Blog"

Open the model file at app/Modules/Blog/Models/PostModel.php, where you can define the table and fields:

<?php
namespace Modules\Blog\Models;

use CodeIgniter\Model;

class PostModel extends Model
{
    protected $table            = 'posts';
    protected $primaryKey       = 'id';
    protected $useAutoIncrement = true;
    protected $returnType       = 'array';
    protected $useSoftDeletes   = false;
    protected $protectFields    = true;
    protected $allowedFields    = ['title','description'];

    protected bool $allowEmptyInserts = false;
    protected bool $updateOnlyChanged = true;

    protected array $casts = [];
    protected array $castHandlers = [];

    // Dates
    protected $useTimestamps = false;
    protected $dateFormat    = 'datetime';
    protected $createdField  = 'created_at';
    protected $updatedField  = 'updated_at';
    protected $deletedField  = 'deleted_at';

    // Validation
    protected $validationRules      = [];
    protected $validationMessages   = [];
    protected $skipValidation       = false;
    protected $cleanValidationRules = true;

    // Callbacks
    protected $allowCallbacks = true;
    protected $beforeInsert   = [];
    protected $afterInsert    = [];
    protected $beforeUpdate   = [];
    protected $afterUpdate    = [];
    protected $beforeFind     = [];
    protected $afterFind      = [];
    protected $beforeDelete   = [];
    protected $afterDelete    = [];
}

Create a migration file by running:

php spark make:migration AddPost

Edit the migration file at app/Database/Migrations and define the structure for the posts table.

<?php
namespace App\Database\Migrations;

use CodeIgniter\Database\Migration;

class AddPost extends Migration
{
    public function up()
    {
        $this->forge->addField([
            'id' => [
                'type' => 'BIGINT',
                'constraint' => 255,
                'unsigned' => true,
                'auto_increment' => true
            ],
            'title' => [
                'type' => 'VARCHAR',
                'constraint' => '255',
            ],
            'description' => [
                'type' => 'longtext'
            ],
            'created_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
            'updated_at' => [
                'type' => 'TIMESTAMP',
                'null' => true
            ],
        ]);
        $this->forge->addPrimaryKey('id');
        $this->forge->createTable('posts');
    }

    public function down()
    {
        $this->forge->dropTable('posts');
    }
}

Use the following command to run the migration to update your database.

php spark migrate

7 Create New Controller - BlogController

Next, create the BlogController:

php spark make:controller BlogController --suffix --namespace "Modules\blog"

In app/Modules/Controllers/BlogController.php, load the PostModel and fetch all posts to display in the view.

<?php
namespace Modules\Blog\Controllers;

use App\Controllers\BaseController;
use App\Modules\Blog\Models\PostModel;

class BlogController extends BaseController
{
    private $postModel;

    public function __construct()
    {
        $this->postModel = new PostModel();
    }

    public function index()
    {
        $data = [
		    'posts' => $this->postModel->findAll(),
        ];
        return view('post',$data);
    }
    
}
?>

8 Create Post View File

Create the post.php file inside app/Modules/Blog/Views. This file will display the posts fetched from the database.


  <!DOCTYPE html>
<html lang="en">
 <head>
   <meta charset="utf-8">
   <meta http-equiv="X-UA-Compatible" content="IE=edge">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>CodeIgniter 4 Implementing the HMVC Architecture Pattern</title>
   <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
   <link rel="stylesheet" href="https://mdbcdn.b-cdn.net/wp-content/themes/mdbootstrap4/docs-app/css/dist/mdb5/standard/core.min.css">
   <link rel='stylesheet' id='roboto-subset.css-css'  href='https://mdbcdn.b-cdn.net/wp-content/themes/mdbootstrap4/docs-app/css/mdb5/fonts/roboto-subset.css?ver=3.9.0-update.5' type='text/css' media='all' />
</head>
 <body>
  
 <div class="container-fluid">
  <div class="row">
  <div class="col-md-3"></div>
    <div class="col-md-6 mb-4">
      <div class="card mb-4">
        <div class="card-header py-3">
          <h5 class="mb-0">CodeIgniter 4 Implementing the HMVC Architecture Pattern</h5>
        </div>
        <div class="card-body">
        <?php foreach ($posts as $post): ?>
        <h2><?php echo $post->title; ?></h2>
        <p><?php echo $post->description; ?></p>
    <?php endforeach; ?>
        </div>
      </div>
    </div>
    <div class="col-md-3"></div>
    
  </div>
  </div>
  <script type="text/javascript" src="https://mdbcdn.b-cdn.net/wp-content/themes/mdbootstrap4/docs-app/js/dist/mdb5/standard/core.min.js"></script>

</body>
</html>

9 Define a Route

Define routes for your blog module by creating a Config/Routes.php file inside the Modules/Blog directory. Group the routes under the blog prefix:

<?php
$routes->group('blog', ['namespace' => 'Modules\Blog\Controllers'], static function ($routes) {
    $routes->get('/', 'Blog::index');
});

Ensure the main app/Config/Routes.php file is set up to include module routes.


$modules_path = ROOTPATH . 'Modules/';
$modules = scandir($modules_path);

foreach ($modules as $module) {
	if ($module === '.' || $module === '..') {
		continue;
	}

	if (is_dir($modules_path) . '/' . $module) {
		$routes_path = $modules_path . $module . '/Config/Routes.php';
		if (file_exists($routes_path)) {
			require $routes_path;
		} else {
			continue;
		}
	}
}

The above code search for /Modules folder, if Modules folder found then it includes Routes.php from each module's Config folder.

10 Folder Structure

Here’s a simplified view of your folder structure:

11 Run Web Server to Test the App

Run the following command to start the server and test the app:

php spark serve

Visit http://localhost:8080/blog to see the CodeIgniter 4 HMVC application in action.

12 Conclusion

That’s all you need to implement the HMVC Architecture Pattern in CodeIgniter 4. Now, you can build modular, scalable applications with ease!

Tags