Newer posts are loading.
You are at the newest post.
Click here to check if anything new just came in.

May 18 2010


HVMC: an Introduction and Application

This tutorial is an introduction to the Hierarchical Model View Controller(HMVC) pattern, and how it applies to web application development. For this tutorial, I will use examples provided from the CodeIgniter from Scratch series and demonstrate how HMVC can be a valuable modification to your development process. This introduction assumes you have an understanding of the Model View Controller (MVC) pattern. We suggest you read our introduction to MVC to get acquainted with the topic before tackling this tutorial.

What is HMVC?

HVMC is an evolution of the MVC pattern used for most web applications today. It came about as an answer to the salability problems apparent within applications which used MVC. The solution presented in the JavaWorld web site, July 2000, proposed that the standard Model, View, and Controller triad become layered into a “hierarchy of parent-child MCV layers“. The image below illustrates how this works:

Each triad functions independently from one another. A triad can request access to another triad via their controllers. Both of these points allow the application to be distributed over multiple locations, if needed. In addition, the layering of MVC triads allows for a more in depth and robust application development. This leads to several advantages which brings us to our next point.

Why should I use HMVC?

Key advantages to implementing the HMVC pattern in your development cycle:

  • Modularization: Reduction of dependencies between the disparate parts of the application.
  • Organization: Having a folder for each of the relevant triads makes for a lighter work load.
  • Reusability: By nature of the design it is easy to reuse nearly every piece of code.
  • Extendibility: Makes the application more extensible without sacrificing ease of maintenance.

These advantages will allow you to get M.O.R.E out of your application with less headaches.

Setting up HMVC in CodeIgniter

To add extra depth to the CodeIgniter from Scratch series, we will be viewing today’s examples in CodeIgniter. I will lead us though the steps needed to get CodeIgniter working with HMVC. Once we’re done with that, I’ll provide a couple of examples. Let’s begin!


To run web applications, you need a web server on your computer if you are not working remotely. Here are recommendations with links to installation instructions:

Step 1. Download and Install CodeIgniter

Go to and click the “Download CodeIgniter” link. If you know how to install it and want to skip past this step click here

Extract the contents of the zip file to your web server’s document root.

Rename the “CodeIgniter_1.7.2” folder to “hmvcExample“.

Move the “hmvcExample/system/application” folder to “hmvcExample/application“. This is common practice with CodeIgniter. The purpose of doing this is to separate the application from the core of the framework. We should now have a directory that looks like the image below:

Open “hmvcExample/application/config/config.php” in your editor of choice.

Edit the site base url to match the location of your install. In my case I would change

$config['base_url'] = "";


$config['base_url'] = "http://localhost/hmvcExample/";

Save your changes and close “hmvcExample/application/config/config.php

Test that we have a working version of CodeIgniter. Open your browser and check your “http://yourhost/hmvcExample/”.
You should be greeted with the “Welcome to CodeIgniter” screen below:

That’s it! You have successfully downloaded and installed CodeIgniter. Now we will move on to making it work with the HMVC extension.

Step 2. Download and Install HMVC Extension

Download version 5.2 of the modular extension from the CodeIgniter Wiki.

In the contents of the zip file are three php files:

Move these three files into the “hmvcExample/application/libraries/” folder.

Recheck your browser. You should still see the Welcome to CodeIgniter screen.

It’s time to add the modules. Create the following directory structure “application/modules/welcome/controllers/“.

Move the “application/controllers/welcome.php” to “application/modules/welcome/controllers/welcome.php“.

Recheck your browser. You should still see the Welcome to CodeIgniter screen.

Create the folder “application/modules/welcome/views/

Move the “application/views/welcome_message.php” to “application/modules/welcome/views/welcome_message.php“.

Do a final check on your browser. You should still see the Welcome to CodeIgniter screen.

That’s it! Modular Extensions is installed correctly.

Login Module Example

Now that we have our HMVC enabled instance of CodeIgniter, I will demonstrate some short examples. For our first example I will show how you can apply user access restrictions to pages or entire modules.

Download and unzip CodeIgniter from Scratch Day 6 source files into your web server. You should end up with a folder called “ci_day6/” alongside our “hmvcExample/

Create the “login” module in our “hmvcExample/application” directory. It should end up looking like this


Create the “site” module in our “hmvcExample/application” directory. It should end up looking like this


TIP: When working with modules I keep a folder named RENAME with the three empty folders controllers, models and views. This saves me a little bit of time anytime I wish to create a new model.

Now we copy over the login module files from “ci_day6/” to our “hmvcExample/“.


Copy/Move each of the above files over as listed below


Next we copy over the site module files from “ci_day6/” to our “hmvcExample/“.


Copy/Move each of the above files over as listed below


The last files to copy over are the global views and CSS and image files. The asterisk (*) denotes folder and all its contents including sub folders


Copy each of the above folders and all their content over as listed below


Open “hmvcExample/application/config/autoload.php” and edit it to look like the this:

$autoload['libraries'] = array('database', 'session');	// Need to Autoload DB and Session

| -------------------------------------------------------------------
|  Auto-load Helper Files
| -------------------------------------------------------------------
| Prototype:
|	$autoload['helper'] = array('url', 'file');

$autoload['helper'] = array('url', 'form');		// Need to autoload url and form.

If you have not already done so from step one, open “hmvcExample/application/config/config.php” and edit it so that the base url is set to your appropriate location.

$config['base_url'] = "http://localhost/hmvcExample/";	// web address. WARNING keep trailing /

Open “hmvcExample/application/config/database.php” and add the appropriate links to your database.

$db['default']['hostname'] = "localhost";		// location of DB server
$db['default']['username'] = "YOUR USERNAME HERE";	// username you use to connect
$db['default']['password'] = "YOUR PASSWORD HERE";	// associated password
$db['default']['database'] = "ci_series";		// The database you want to use

Open your browser to test that the login page displays “http://localhost/hmvcExample/index.php/login

Now to make this login function, we need to create the membership database table. For this, we need to create a table in your PHPMyAdmin.

Select or create your “ci_series” database.

In the sQL tab, paste the code below into the textarea and click go

CREATE TABLE  `ci_series`.`membership` (
`first_name` VARCHAR( 32 ) NOT NULL ,
`last_name` VARCHAR( 32 ) NOT NULL ,
`email_address` VARCHAR( 64 ) NOT NULL ,
`username` VARCHAR( 32 ) NOT NULL ,
`password` VARCHAR( 32 ) NOT NULL

With the membership table created, we click on the create account link on the login page and add a user to the database.

Login in as the user and confirm that you are now in the “site/members_area” of the site. It should look similar to the image below:

Click “logoff” link and try to manually go back to the members area. you will see that you no longer have permission to do so.

So we have our triads grouped, but we are still not quite in HMVC mode yet. In the site controller we find a function called is_logged_in().

	function is_logged_in()
		$is_logged_in = $this->session->userdata('is_logged_in');
		if(!isset($is_logged_in) || $is_logged_in != true)
			echo 'You don\'t have permission to access this page. Login';

This is a login related function. In MVC mode, this is required because site cannot access login. With HMVC we can fix this.

Cut the is_logged_in() function out of “applications/modules/site/controllers/site.php

Save site.php without the is_logged_in() function.

Open “applications/modules/login/controllers/login.php“.

Paste the is_logged_in() function into the class.

Save login.php

Open “applications/modules/site/controllers/site.php“.

	function __construct()

In the __Construct() function, we make the HMVC call to login’s is_logged_in() function, as seen below:

	function __construct()
        // Format: modules::run('module/controller/action', $param1, $param2, .., $paramN);

MVC 101 Complete

There you have it! We have successfully altered day six code into HMVC format. The site module now requests the login check instead of having to use its own. While outwardly we observe no difference, the site design has fundamentally been changed. All login functions are now where they belong: inside the login triad. This may seem like a lot of work with small reward but it is not so. Any login changes can be made once. The internal structure of the triad can be edited without having to change the entire application in response. Code replication for other controllers is no longer required. Last but not least, all the related code is in one handy location. This tiny step may not WOW you but when we delve deeper into bigger, complex applications, the M.O.R.E. apparent it will become how effective the HMVC pattern is.

Members Section Example

We are now going to uncover more of HMVC’s power. We just demonstrated how to call a module from a controller. There are other places you can do that as well. HMVC was build with the User Interface (UI) in mind. We get to call modules from our views as a result. This is where the power of HMVC can really shine.

When calling HMVC from a view you will use the same modules::run(). There is only one requirement when doing this. The resulting output from the call must be a html snippet and not a complete view. This is because we are already inside a view at the time we call the run function. We will see this in action down the page as we edit the site module views.

Step 1. Edit Login Controller

We are going to create a block which appears on the top of every page with our user’s name, important links, and logout option. Widgets like this are commonplace on sites today. The image below illustrates the end result.

Open “applications/modules/login/controllers/login.php“.

    function cp()
        if( $this->session->userdata('username') )
            // load the model for this controller
            // Get User Details from Database
            $user = $this->membership_model->get_member_details();
            if( !$user )
                // No user found
                return false;
                // display our widget
                $this->load->view('user_widget', $user);
            // There is no session so we return nothing
            return false;

Paste/Write the code above into the login controller.

cp() receives information from the membership_model function, get_member_details(), which we create in the next step. If a user is found we will display the view snippet detailed in step three. From there we should get the desired block illustrated above.

Save the changes you made to login.php

Step 2. Edit Membership Model

You will notice that we called a get_member_details() from the membership_model. This function gets our user information from the database and will be accessed from a few different sources. We are going to work on that now.

Open “applications/modules/login/models/membership_model.php“.

	function get_member_details($id=false)
		if( !$id )
			// Set Active Record where to the current session's username
			if( $this->session->userdata('username') )
				$this->db->where('username', $this->session->userdata('username'));
				// Return a non logged in person from accessing member profile dashboard
				return false;
			// get the user by id
			$this->db->where('id', $id);
		// Find all records that match this query
		$query = $this->db->get('membership');
		// In this case because we don't have a check set for unique username
		// we will return the last user created with selected username.
		if($query->num_rows() > 0)
			// Get the last row if there are more than one
			$row = $query->last_row();
			// Assign the row to our return array
			$data['id'] = $row->id;
			$data['first_name'] = $row->first_name;
			$data['last_name'] = $row->last_name;
			// Return the user found
			return $data;
			// No results found
			return false;

Comment your code! It’s a best practice and will help others understand what you wrote.

Line 01: The function call has a default variable $id. This allows us an option of finding a user by ID rather than by username. This made optional by setting it to false in the declaration.

The rest of the function is straight forward and well commented. We query the membership table for a user via username or ID. The result is saved to the $data array and returned. All other outcomes return false.

Save the changes you made to membership_model.php

Step 3. Create User Widget View

The third and final piece to the widget we are creating is the xhtml snippet, which we can put into any other view. This is called by the login controller’s cp() function which we just wrote.

Open “applications/modules/login/views/user_widget.php“.

<code style="font-family: Monaco, Verdana, Sans-serif;
                 font-size: 12px;
                 background-color: #f9f9f9;
                 border: 1px solid #D0D0D0;
                 color: #002166;
                 display: block;
                 margin: 14px 0 14px 0;
                 padding: 12px 10px 12px 10px;">
	<?php echo $first_name.' '.$last_name; ?> &middot;
	<?php echo anchor('site/members_area', 'Dashboard'); ?> |
	<?php echo anchor('site/profile/'.$id, 'Profile'); ?> |
    <?php echo anchor('site/messages/'.$id, 'Messages'); ?> |
	<?php echo anchor('login/logout', 'Logout'); ?>

Note: It is not a good practice to use inline styling. I opted to put this one instance of inline style for the sake of remaining on topic.

This styled code block takes the information passed from the cp() function. We generate the links using CodeIgniter’s URL helper’s anchor() function. More information about the user guide can be found on

After working on those three files we will test the “login/cp” page. We should see something like the image below. Note: You need to be logged int to see it. Be sure to do so before checking the page or you will see nothing.

Step 4. Edit Site Controller

The links in the snippet to profile and messages will return an error for the moment. This is ok because we have not created those functions yet. Lets do that now.

Open “applications/modules/site/controllers/site.php“.

class Site extends Controller
	function __construct()

	function members_area()

For the purpose of this example we shall remove the…


…from the function so that we can make specific parts private and have other parts public.

We want only logged in users to access the members dashboard area. So we will use the modules:run HMVC function and call the is_logged_in check from the login controller. We then load the logged_in_area view file which will be edited further down the page.

	function messages()
		$user = $this->membership_model->get_member_details($this->uri->segment(3));
		if( !$user )
			// No user found
			return false;
			// display our widget
			$this->load->view('member_messages', $user);

Like members_area(), we only want logged in users so we have included the is_logged_in check. We have already written the code on how to get user details from the database so we will load the login model, membership_model. This will allow us to get the user information via the get_member_details() function. The third URI segment being passed into that function is an id for the user we wish to get messages for. For example, if the url was:


Then our function get_member_details() would be receiving “43″ as an input variable. Depending on the result of get_member_details(), we are either shown the view: member_messages or we get nothing (as a result of a failed query).

	function profile()
		$user = $this->membership_model->get_member_details($this->uri->segment(3));
		if( !$user )
			// No user found
			$data['main_content'] = 'member_profile';
			$data['notice'] = 'you need to view a profile id';
			$this->load->view('includes/template', $data);
			// display our widget
			$user['main_content'] = 'member_profile';
			$this->load->view('includes/template', $user);

Just like any social network; we want the profile pages to be public. So we have not included the is_logged_in check. Just like messages, we call the login triad’s membership_model and query the database for our desired user. In this case, if no user is found, we quit a bit more gracefully. We also notify the visitor that an id needs to be specified. With a successful result, we see the member’s profile.

Step 5 Edit Logged In Area View

Open “applications/modules/site/views/logged_in_area.php“.

<!DOCTYPE html>
<html lang="en">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<?php echo modules::run('login/cp');?>
	<h2>Welcome Back, <?php echo $this->session->userdata('username'); ?>!</h2>
     <p>This section represents the area that only logged in members can access.</p>

Overwrite the contents of the file with the code above.

Line 08: HMVC is put into action here. Our view calls the “login/cp” function, and echoes out the html snippet exactly where we tell it. Notice how we didn’t have to prepare anything ourselves? It’s all handled internally by login for us. Handy isn’t it?

Save the changes you made to logged_in_area.php. Your finished page should display like:

Step 6. Create Member Messages View

Create a new view: “applications/modules/site/views/member_messages.php“.

<!DOCTYPE html>
<html lang="en">
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
	<?php echo modules::run('login/cp');?>
	<h2><?php echo $first_name; ?>'s Messages</h2>
     <p>This could be where the messaging system gets displayed</p>

Write or paste the code above into the newly created file.

This view is pretty much just a clone of the members area to test that login holds on multiple pages. There is one difference: we fished some information from the login module’s membership_model. This is shown as the $first_name variable.

The point of getting user information here would be to pass it on to a module which would return a snippet with the user’s messages.

Save the changes you made to member_messages.php. Your finished page should display like:

Step 7. Create Member Profile View

Create a new view: “applications/modules/site/views/member_profile.php“.

	<?php echo modules::run('login/cp');?>
    <?php if( isset($notice) ): ?>
    <h2>Member Profile Pages</h2>
    <p><?php echo $notice; ?></p>
    <?php else: ?>
	<h2><?php echo $first_name; ?>'s Profile</h2>
     <p>Put all the good wholesome profile info here!</p>
	<?php endif; ?>

Write or paste the code above into the newly created file.

We have an if statement which detects whether a user was found or not. If not, we get brought to an error page stating we need an ID to view a profile.

Again, we retrieve the user information. Just like messages we would use this to retrieve the user’s friend list, latest blog entry, and activity feed, etc.

Save the changes you made to member_profile.php. Your finished page should display like:

What Happens When We Logoff?

Because we want the profile pages to be public, it should still display. Minus the user widget of course.

When logged in, and we go to profile without a third uri segment we see our own profile. Logded off, we will be shown the error below.

We should not be able to view the message or dashboard. When we check the messages page we are greeted with this:

We’re Done

That’s it! We have added more depth to our initial example and demonstrated the different ways to use HMVC.

  • Call modules::run() from a controller.
  • Echo modules::run() from a view to display a HTML snippet.
  • Load a model from another module.

I hope this has been an enlightening experience. HMVC is an extraordinary pattern which makes applications more robust. It is well worth the investment. Give it a try. I promise you won’t ever want to go back to vanilla MVC!

November 06 2009


Book Review: Zend Framework 1.8 Web Application Development

If you are looking into buying a book to learn about Zend Framework, chances are you are already set on using Zend Framework to build your next project. Today, we will be looking at Zend Framework 1.8 Web Application Development by Keith Pope, published by Packt Publishing.

First of all, you’ll notice that this book is based on Zend Framework version 1.8, and as of writing this review, the latest stable release of Zend Framework is 1.9.4. This is not an issue, because 1.9, even though it brings new features such as PHP 5.3 compatibility and RESTful web services, does not change its structure or any part of the system that might have impact on your learning.

Flow of the Book

The flow of this book is heavily inspired by the famous Ruby on Rails book, Agile Web Development with Rails, where the author invites you to join the process of building a demo application, which in both cases is a shopping cart system. Judging by the feedback of the Rails book, most people feel quite comfortable learning a framework this way, some don’t. I guess if you are not a fan of following a defined learning structure, this book probably isn’t for you.

Short but Sweet

It is a relatively short book, with only around 350 pages. As a result, this book expects you to be comfortable with working with PHP 5 and have a solid grasp of Object-Oriented Programming. If you aren’t already familiar with PHP, or PHP 5’s OOP features, I highly recommend you to polish up the said skills.

MVC Still Rules

The first two chapters of the book focus on the MVC (Model-View-Controller) pattern. As the author mentions at the start of the book, Zend Framework is a loosely coupled framework; it does not enforce the MVC principle. However, given the popularity of MVC within the web development community, it is definitely worth while to learn how to write an application in MVC. Chapter one explains the basics of MVC whilst chapter two explains the request/route/dispatcher/response family. These two chapters will set up the foundation nicely for you and get you to understand the basic structure of a Zend Framework powered MVC application.

Adventure of the Store-Front App

Chapter three to nine contain the actual ‘adventure’ where you as the reader will be riding along with the author on the journey of creating a store-front/shopping-cart application. During the process, the author tells you not only what to do, but also why to do them. A good example is the ‘fat controller skinny model’ vs ’skinny controller vs fat model’ comparison, the book illustrates each and tells you why you should stick with the latter.

Chapter ten wraps up the store-front application with some more common tasks such as bootstrapping modules and sharing common application elements.

Code Optimization, Caching and Testing

Chapter eleven touches on a very practical topic: code optimization and caching. This is especially beneficial if you’re to run a large volume web application or if you have limited hardware resources. Pay special attention to the Zend_Cache section as the author tells you how to integrate it effectively in your application in order to achieve the best result.

The last chapter, chapter twelve, introduces you to Zend_Test, a testing framework that utilizes PHPUnit.


To wrap the review up, I think this is an excellent book on Zend Framework provided you:

  • already have a good understanding of PHP;
  • already have a good understanding of OOP;
  • can follow the rather forceful learning flow;
  • know how to learn with initiative (e.g. do your own research!).

This book sits well in the market, as it aims primarily at web professionals who most likely are already experienced with PHP and perhaps some other PHP frameworks, and don’t have time to read books with 1000’s of pages.

You may purchase this book via Packt Publishing’s website.

Older posts are this way If this message doesn't go away, click anywhere on the page to continue loading posts.
Could not load more posts
Maybe Soup is currently being updated? I'll try again automatically in a few seconds...
Just a second, loading more posts...
You've reached the end.
No Soup for you

Don't be the product, buy the product!

YES, I want to SOUP ●UP for ...