1. Where Does This Go?

A common question in the forum of any framework is, “Where do I put this information?” The answers are usually fairly varied, though most do stick close enough to traditional MVC patterns. The reason it varies so much, though, is simply due to the types of projects each developer has worked on and the environments those projects were created in. Freelance developers might have stumbled onto the way they use the data based on sheer luck or hours reading blogs. Large companies might have someone dictating the organizational patterns used by the rest of the developers, or even internal base classes which make a specific structure easier or more productive.

In this chapter, I’m going to show you the way that I approach this subject. If you’re new to CodeIgniter, I believe that adopting these methods will help keep your projects organized and easy to maintain. If you’ve been using it for a while, or are coming from another framework, and your habits are slightly different, that’s ok. I’m not here to convert you, but I will let you know why I think this approach works best. From there, you’re free to choose how you want to use it. I won’t come to your business and critique your work. And CodeIgniter doesn’t mind, either. It’s flexible enough to support almost anything you can throw at it.

MVC - Easy as 1 2 3

CodeIgniter is based loosely around the MVC pattern - Models, Views, and Controllers. There are many variations on exactly what goes in each, so let’s first cover what each of those are so that we’re all on the same page.

Models

Models are the central piece of the puzzle. In traditional definitions of MVC, they were responsible for notifying the views of changes and letting the controllers know so that it could change the available commands. In our web world, the model layer is responsible for the data itself and handling any business logic around that data.

In some frameworks the model is split into two layers: the data access layer, which only handles getting the information from the database; and the business logic layer which handles validation of data, ensuring formatting is correct on the way in and out, making sure that other items are updated when an action happens in this model, etc. In CodeIgniter, all of this has a tendency to be handled within the Model itself, though I’ll make a case for splitting it between Models and Libraries later.

Views

Views are simply displays of data. They are normally “dumb” HTML files, though newer thick-client applications may have very smart views that handle updating themselves in a very dynamic way. Even though they may provide a lot of interaction with the user, they are still a way to view that data, though JavaScript may add additional layers of MVC at that point.

While they are primarily used to display HTML to the user, they can also be used to format an XML sitemap or an RSS Feed, CLI output, or any other format you desire. Views can represent a whole page, but will more often represent fragments of the information to keep repetition to a minimum.

Controllers

Controllers take care of moving the data between the model and the views, and directing traffic based on user actions. For example, when a user submits a form, the controller collects the data and shuffles it off to the model, which should ensure the data is valid. The controller then tells the View (or JavaScript layer) whether it was successful.

There are a number of reasons to keep your controllers light and relatively dumb, but I’ll focus on one big reason. It keeps all of your application-specific rules in one central place: the Model layer. That model can then be used in different applications with the same result.

You might have an application that is already up and running. The client comes back and asks for an API for that data so they can make a mobile application. With the data and business rules all handled in one location, you simply need to share those models with the new API application and any changes in business logic will be ready for both applications.

Or you might be working for a large insurance company. Because of the way their data needs to be handled, they have a number of separate applications that all use the same data. And that data needs to be handled the same way, whether it’s generating millions of monthly reports to send to their clients, or allowing the administrators to run “what if?” scenarios on the data to see how potential changes might affect the company.

So, What Goes Where?

Now that we’ve covered the basics of MVC and have a common way of looking at things, let’s look at 2 more types of files that CodeIgniter supports: Libraries and Helpers. Then, we’ll explore some common use-cases and look at ways to organize these files to help solve these problems.

Helpers

Helpers are intended to hold procedural functions. These can be any functions that are outside of a class.

“Wait!” I hear you yelling. “This is supposed to be OOP programming. What gives?!” First, nothing will ever be 100% object-oriented. You always have to have your bootstrap file that runs through and instantiates all of the needed classes. So forget the idea that you’ll ever get rid of procedural code and functions. It’s a lie.

Helpers, then, are used to provide new functions that can be used easily to provide custom functionality. You can use these functions to provide compatibility functions for when the command doesn’t yet exist in your version of PHP. They can be used in form validation callbacks to provide custom validation methods. They can also be used to do some simple or common formatting within views since, once loaded, they’re always available. You’ll also find third-party code that is implemented as a function that you want to use. A common example, for me anyway, is the Markdown Extra libraries. For years I’ve used those, though I’ve recently switched over to the PHP League’s CommonMark libraries. (No, I didn’t switch because it was an OOP solution.) The fact is that functions still have their place, and helpers provide a simple way to load them. Simple as that.

Libraries

Libraries were EllisLab’s way of making it easier to load any class that was not a controller or model. This was before the days of namespacing and good autoloading in PHP. Libraries can be used to incorporate third-party code, though more often than not, you’ll simply use autoloading and won’t need anything special for third-party code.

Libraries can be used to provide common functionality that you want accessed by different parts of your app. They help provide a single point of entry that makes it simple to maintain consistency in business rules. They’re ideally used for creating focused, single-responsibility classes, like Benchmarking, UserObject, Article, etc.

The thing I want to emphasize here, though, is that they were the way to handle any class that was not a controller or model. I think this is a very important concept when using CodeIgniter so that you don’t paint yourself into a corner when it comes to using other classes. Libraries are not just a file that must contain stand-alone information that can be passed from project to project, though that is the traditional role in CodeIgniter applications. It’s just not the only use for libraries. Many new paradigms are becoming common in PHP programming that have come from more traditional software development. You can now have Entity Models, Factories, Adapter classes, Decorators, and many other classes that help fulfill different design patterns. The one thing they all have in common is that they are a class. In CodeIgniter, the only way provided to load these classes is as a library. The other options are to hardcode require statements or use an autoloader like Composer. Personally, I highly recommend Composer, and will discuss that more in a later chapter.

Earlier, I said I’d make a case for splitting the business logic across Libraries and Models. Let’s tackle that now. The more I work with CodeIgniter, and PHP in general, the more I find situations where following this simple rule of splitting it into two layers would have saved me time refactoring. So, to save you that time, here’s the primary reason I recommend splitting them up. Depending on how you structure your app, you might find other benefits along the way.

By keeping the Library as your object’s unchanging, backwards compatible API, and using your Model as a basic data-access layer, you never have to worry about how you get that data. If your company decides that they need to switch this one resource from a persistent MySQL storage base over to using a “temporary” Redis-backed solution, you’re ready because you can hook up to any model. You could even provide both in different situations, maybe with the lightning fast Redis as your primary store that’s backed up occasionally in the background to MySQL for permanent storage.

The Library can also provide formatting of objects before they get to the rest of your code. Then, if your database schema changes, it won’t automatically break your application because the library is keeping a consistent format. Alternatively, you might have a reporting resource that needs to pull in data from several database tables, and process the results, before returning it to the rest of your app. While you could do that in your Model layer, a library provides a cleaner mental picture of how the app works and makes changes that much clearer.

One method of implementing this separation is known as the Repository Pattern, and becomes more important as your application and team get larger and more complex.

As with anything, though, application architecture is more art than science. Splitting up the layers in smaller situations might be overkill. On large projects I’m becoming a big believer in it.

Third Party Code

There are two common methods for handling third-party code effectively within CodeIgniter. Third-party code could be a single class or several classes making up a full-featured suite of related code, like Monolog.

The first, and becoming increasingly more popular, method is to use Composer to bring in and manage third-party code. In this case, it will all be handled for you behind the scenes and you don’t have to worry much about it. More details will be given in Chapter 13: Composing Your Application.

What about libraries of code which are not packaged up nicely for Composer? One example of this might be libraries provided by a credit card processing company. If they don’t provide a Composer package, then you’re stuck trying to figure out how it fits within your application’s structure, and how to load it. My advice? Forget about CodeIgniter, and remember that you’re simply programming in PHP with CodeIgniter to help out.

In these cases, place the code in its own folder within /application/third_party and simply use include() or require() to load the file, then you can make a new instance and use it however you need to. To make this a little easier and less fragile, be sure to use the APPPATH constant when you include the file.

require APPPATH . 'third_party/mypackage/myClass.php';
$package_class = new myClass();

Use Cases

So, let’s dig into a few examples of how we’d implement some code for some real-world use cases.

Simple Blog System

For the first example, let’s use the standard Blog system. This isn’t anything very fancy, just the basics. We are going to look at the front end part of the module, ignoring any admin code.

Controller - The Controller will simply handle moving things back and forth between the library and the views. It might have the following methods:

  • index to display the 5 most recent posts with their body text.
  • show to display a single post with all details, comments, etc.
  • category to list all posts belonging to a single category.
  • archives to display all posts published within a year and month passed in the URI.

In addition to these page-specific issues, it should take care of any common data that will need to be displayed on all of the blog pages. It would likely need to grab a list of the most recent posts and make it available for the sidebar. It might also need to grab a list of tags or categories for the sidebar.

Library The library would contain very specific methods for grabbing the data from the database, by way of the model, making sure it’s in the proper format, and returning the data back to the controller. It might have methods like recent_posts(), posts_by_category(), posts_by_month(), etc. This would need a method to display a simple list of recent posts with a headline, image, and URL for sidebars.

Model The model would contain a set of basic methods for getting data out of the database, like find(), find_many(), insert(), etc. It would validate each field whenever a new element was inserted or updated. It might contain logic embedded within the various methods to destroy a cache whenever a record was updated or created, etc.

Views There would be several views, but you want to minimize repetitive display of posts as much as possible. This means you want to create a single view responsible for displaying the post itself. You could have a little bit of logic here to determine if it is showing a full post or just an excerpt. This post view could then be re-used by the category page, the archives page, the overview page, and the individual page. You would also have smaller views to handle the recent posts, or a popular posts block that would end up in the sidebar.

Views should not have any business logic in them. The logic in a view should be restricted to simple things related to the display of the data, like if...else blocks so that you can provide good blank slates when no data exists. Almost everything else should be handled by your controller, a library, or your model.

Survey Generator App

This app allows a user to create a survey by selecting from a number of question types, like yes/no questions, text-only answers, multiple choice, etc. The questions must be reusable between surveys, have their own scoring rules, etc. What you end up with is a number of different special cases for each question type.

For this example, we won’t focus on the entire application, but instead drill down into how we might use the standard file types for this situation.

Libraries To handle the different question types elegantly, we will need to create a single BaseQuestion class. This class would implement default, generic versions of the functions needed by a question, like generating an answer based on the scoring rules for that question, determining maximum possible score, etc. Each question type would then need its own class that extends from that BaseQuestion to customize the way it handles scoring questions, etc.

In this case, I would be tempted to use CodeIgniter’s load->library() function to load the individual questions, but instead I use a require_once in each of them to pull in the BaseQuestion class. This is mainly because I don’t feel the Loader really needs to know about the base class and use storage and memory for that.

If I was using Composer in the project, then I would skip the libraries and make them simple namespaced classes, since it would make everything a little cleaner. If you’re not familiar with Composer, I highly recommend you take some time to learn it, because it can change the way you code. A later chapter is devoted to using Composer with CodeIgniter, and there are many, many resources available on the internet to get you up to speed with using Composer in general.

Additionally, you will need a central library for handling and formatting your question data consistently. This might need to pull in data from several models in order to provide quality statistics and other reporting features.

Models While you will often end up having a single model represent a single database table, when you are dealing with applications that need to return statistics, like this app would provide to the survey owner, you will often need to switch your thinking. Instead of a single table, a model can represent a single domain, or area of responsibility. This means it can pull in data from a number of tables to generate the results it needs.

In this example, we could have a Survey_model that, in addition to its standard required functions, would be able to pull in data about statistics for each survey. You could also create a separate Survey_stats_model that you would use within the Survey_model to keep a clean separation of responsibility.

Views While you would have all of the standard views for displaying the various forms for making the survey, and for the user to fill it out, a little special consideration would be needed for the questions. Since each question will have different needs when it comes to displaying them, you will need to create new views for each question in three different modes: create/edit, answer, and reporting. Then you can loop through the available questions and pull in a view for each depending on its type.

Controller Design

While we’re talking about use-cases, I want to touch an issue for less-experienced developers: controller design. What I mean by this is how controllers are broken up, which methods they contain, etc.

It’s all too easy to put too much in a single controller. Like anything else, though, you need to keep controllers clearly organized and simple to understand. Both for you, when you come back to debug something in a few months, or for new developers on a project that are forced to try to understand what is where.

The simplest way to look at this is to write out a list of what you want your URLs to be, then work from there. This helps to keep you thinking about the problem clearly, without getting caught up in the intricacies of the code required for the application.

Let’s run through an example, and I’ll explain more as we go along.

This application is going to be a Customer Relationship Management software that allows you to manage your clients, potential clients, supplier companies, and cold leads. Since we want to be able to view and manage the individual people as well as the companies, we could start our URL mapping with something like the following.

/people
/people/add
/people/remove
/people/{id}/contact
/people/{id}/history
/companies
/companies/add
/companies/remove
/companies/{id}/people
/companies/{id}/people/add
/companies/{id}/people/remove

With this starting point, it would make sense that you have one controller called people and one controller called companies. Inside each of those, you would have a method to handle the various actions, using the router to allow for the object/{id}/action URLs to map to a class and method like People->contact($id).

In addition, you would likely want some AJAX methods for adding notes to people or companies. You might also want AJAX methods for adding reminders to the app’s calendar so that you’ll know to follow up with the client in 3 months. I’ve seen a natural tendency to want to create a single AJAX controller to handle all of that. However, that solution tends to create very large classes that are difficult to maintain, and it occasionally makes it difficult to locate the proper method.

Instead, you should create separate controllers for each of the areas of concern, like notes or reminders. In smaller applications, these controllers could hold both the AJAX and non-AJAX methods. Once your application starts to grow, you should consider creating an AJAX directory located at /application/controllers/ajax/ and putting any AJAX-specific controllers in that folder. This makes everything very clear for you and any other developers. It also makes it very simple and logical to locate the method you have to edit.


Another way to start discovering the structure of your controllers is to look at your site’s main navigation from the designer’s mockups. This can be especially helpful if your actions are not all based around nouns (like people or companies). You might have a client area with main navigation focused around a Dashboard, Survey Results, and Leaderboards. In this case, you might be tempted to simply combine those four or five pages into a single controller called clients. I think a better way would be to create a new directory to hold several new controllers.

/application/controllers/clients/
/application/controllers/clients/Dashboard.php
/application/controllers/clients/Results.php
/application/controllers/clients/Leaderboards.php

While it might seem at first glance that each page will only have a single method in it, you will often find that to be untrue. The Leaderboards controller would have the method to display the leaderboards, the index() method. It might also have additional methods to help view other aspects of the boards, for example by a certain year, a certain client, etc. It is possible to handle all of that with a single method and filter the results based on $_GET variables, but it is clearer to the end_user if you handle each aspect in a different method within the same controller, because the URL will tell them exactly what’s going on.

Leaderboards->index()
Leaderboards->by_year($year)
Leaderboards->by_company($company)

It also encourages you to wrap your logic up into a neat library or model so that you don’t repeat code. Which is what you should be doing in the first place.


As already mentioned, the purpose of all of these separations are to make things as easy to find and digest, mentally, as possible when you come back to the project, or when you have multiple developers working on the project together, or a new developer takes over the project from you. All of your decisions should be based around those aspects, and how you can make things clearer and more apparent to anyone involved. It doesn’t hurt your reputation, either, to have people talk about how your code is easy to work with and clean.

Packages

While we’re talking about where your code should go, it would be remiss to overlook packages. Packages allow you to bundle nearly any of the standard CodeIgniter files into a “package” that you can easily redistribute. You can include any of the following file types: libraries, models, helpers, config, and language files.

You’ll notice the one missing file type is controllers. This means that you cannot route user actions to anything within that package, but they still have great uses. EllisLab originally added packages to CodeIgniter when they decided to use CodeIgniter as the base of their Expression Engine CMS. They needed a convenient, high-performance way to include third-party modules without interfering with the application or the system.

Why Packages?

I’ve seen three primary reasons for using packages. The most common reason is simply to keep code which shares a common purpose wrapped up in a neat package that can be easily distributed and reused. You might make it available on GitHub for others to use, or you might want to keep a library of common code that you’ve used on projects for your own use. With each new project you can simply pull in the functionality, build a controller to interact with it, and you’re set. You might even have a number of smaller sites on one server that all reference shared code for additional functionality.

Some teams of developers like to use packages or modules as an organizational tool. A single developer, or a small team, would be tasked with working on one dedicated part of the application. This keeps their code isolated and simple to maintain.

The last reason is to separate out common code that you want to share between multiple applications. You might be working on a large site for selling automobiles with an admin area, a dealer area, and the front-end customer area. To keep things prepared in case your application takes off and you need to move each area to its own server, you might choose to keep each of those three areas as a separate application. You want them to share the libraries and models, though, to avoid any duplication. You could create a new common directory and make sure that your other applications know about this new package. Then, when you deploy, you can have a build script delete the unused application from that server, or simply copy only the required application and the common folder into place. This will be discussed in detail in Chapter 9.

Using Packages

While the user guide gives you all of the details, we’ll quickly cover them here so that you understand not just how to set them up, but how they work and why they were designed this way.

A new installation of CodeIgniter doesn’t know anything about your packages or where to find them. It also won’t look for them when trying to find a library or other file, and this is great for performance. The fewer directories that the system has to scan for files, the faster it can find what it’s looking for. So, you have to explicitly tell the system where to find the package, either through autoloading or at runtime.

When you tell it about the package, it will add a new directory to scan for any requested files (except controllers, of course). These directories are then scanned on each load request, starting with the main application folders, then branching out into the packages, in the order they were added. This keeps any packages from overloading core functionality, which is generally a good thing.

Autoloading

You can tell CodeIgniter to “autoload” packages by adding the entry to application/config/autoload.php.

$autoload['packages'] = array(APPPATH . 'third_party', '/usr/local/shared');

Autoloading of packages is extremely light-weight since all it does is add the directories to the paths to be searched when loading files. No files are read, it doesn’t even confirm that the directories exist before adding them. This is the perfect solution if you have a common package that you will always need to use. Set it once in the autoload config file and forget about it.

Runtime Package Management

If you want to add packages at runtime you can use the add_package_path() method.

$this->load->add_package_path(APPPATH . 'third_party/' . $path);

This can be used a couple of different ways. You could load up a list of modules that are installed and active, then loop over them, adding each module’s package path in the controller’s constructor.

foreach ($modules as $module => $path) 
{
    $this->load->add_package_path($path);
}

However, this creates an unneccessarily large number of folders that have to be scanned through each time. To increase performance, you can limit the packages used in some fashion that allows you to add the package, call its functionality, then remove the package path immediately. This way no extra paths are stored unless they are needed.

$this->load->add_package_path($path)
           ->library('foo_bar')
           ->remove_package_path($path);
$this->foo_bar->do_something();

Modules

The next logical transition that many people move on to from the built-in Packages are Modules. Modules simply allow you to add and route to Controllers. Other than that, they are the same thing as CodeIgniter’s Packages. These carry all of the same benefits as packages, so I won’t go over them again here.

There are currently two solutions for adding module support to CodeIgniter 3. The first is WireDesignz’ Modular Extensions - HMVC. It’s the oldest and most well-known of the two. The second is Jens Segers’ CodeIgniter HMVC Modules, which takes a slightly different approach, but achieves the same goals.

After running both of them through a series of un-scientific tests, I found the performance of both of them to be close to native CodeIgniter speeds. They do both have a small impact, but not enough to worry about in the real world. When running under PHP 5.5.9 with Opcode caching turned on, the difference was less than 10% fewer requests served than on raw CodeIgniter. Of the two, Jens had the edge at being slightly faster.

So, for storing modules, either one works very well, and both have their perks. WireDesignz’ has a few more features, like integrated autoloading of files from the libraries and core directories, while Jens’ has more options for how the router locates the controller and method to run. WireDesignz’ has a known complication with the Form Validation library, but the solution is listed on his site and fairly easy to implement. Jens’ didn’t say anything about that on his site, though I have had the same issues with it in the past.

The biggest difference between the two are how they handle the HMVC, or Hierarchal Model View Controller setup.

HMVC

HMVC is simply a fancy way of saying modules that contain Models, Views and Controllers, and allowing you to call the controllers from other controllers like a library. In practice there are two reasons that people like to use HMVC solutions with CodeIgniter, instead of being happy with simple modules.

The first is for more of a “web services” architecture that allows modules to behave as mini-applications in their own right, and be easily moved to another server if you need to scale your application. Jens’ solution supports this type of HMVC, but in a limited manner. For a true HMVC solution to work with web services like this, you’d have to be able to route across some form of connection, like a standard HTTP connection. Jens’ is not designed to do this. Instead, it merely provides the ability to organize your code in a hierarchy of MVC triads. Depending on who you ask, this can be a good thing or a bad thing. WireDesignz’ solution does something similar here, by allowing you to load a controller and then use it like you would any other library.

The second use is to create reusable “widgets” that make it simple to insert small chunks of HTML into multiple views, but without the headache of having to load that information in every controller. This is handled by WireDesignz’ solution but not by Jens’.

So it boils down to one question: should you use HMVC instead of just plain modules? My answer is no. While I’m a huge fan of modules for code reuse and distribution, the other abilities of HMVC seem to pale among their complexities, especially in the CodeIgniter world.

CodeIgniter was never designed to have what amounts to child requests being processed in a parent request. At its core is the way everything belongs to one central core element (or all controllers/models through the Controller instance) that is a singleton. Whenever you load the controller again, it creates a nested version of this controller. It quickly becomes a messy situation where you cannot always trust that $this is what you think it is. This is very obvious when you have to start tweaking things to get Form Validation to work. As a workaround, the HMVC solutions create another instance of the singleton and pass that around. While that can work well in most cases, it’s also, I believe, what has caused the issues you see with the Form Validation library not working correctly.

The headache that it can cause during debugging is not worth the additional benefits to me. While I like the idea of reusable “widgets” in the view layer, it’s simple to code a solution in a single file, and we will cover that in Chapter 4: Showing Your Work.

Closing

Hopefully, this chapter has helped clear up any confusion about where things go in your application. As you’re working on your applications, though, remember that you don’t need to stress overly much about it. I’m sure people will argue with me, but as long as things are in the “generally correct” location, you will be fine. There is no perfect answer for every situation, but I think the advice I’ve given here will help to prevent situations in which major refactoring due to bad structure will be needed.

Just keep striving to learn from your mistakes, implement those changes in the next project, and keep moving forward. Having stuff in the “wrong” place usually won’t break your application. Besides, you can always refactor later if you need to.