Updated Codeigniter template
I decided a couple of weeks ago to start putting the new things I’ve learnt over the past six months into my codeigniter template on github. This is mainly for my own use when starting each new project to be able to clone, but it’s in a public repository and it might be useful for others to take it as a starting point as well.
Goals
The goals I set out when putting this template together were a combination of two main things, Boilerplate code to help you start out with a solid structure and common app setup code that you will usually rewrite every time. Alongside these I have altered some of the default settings of the framework to tighten security and aid with rapid development.
Boilerplate code to keep things well structured from the beginning of a project
The boilerplate code put together is a combination of things I have learned from dealing with small - medium sized web applications over the past 18 months. I started out with the common areas of a site that could end up pieced together badly if not done right from the start. One of the main issues with a streamlined constantly changing web application can be user authentication and access control, with some layered abstract inheritance in the MY_Controller we can help structure the application to leave a bit of breathing room to split access up into 3 or 4 main categories and share standard functionality between these areas. One thing a lot of small web applications lack is a unified error reporting system, for during development and to log errors whilst the project is in a production environment. The use of Exceptions is a must throughout the system for true error handling and stack trace abilities.
Common application setup code
Similar to boilerplate code in a way is the common things that you setup on each web application, which would be a lot quicker to strip out for the apps that don’t need it, than to add it in for the ones that do. Various things have been added to this install including a template library, bcrypt library for password hashing and a basic user model and authentication pages (login, register etc).
User Authentication
Nearly all web apps will need some for of user authentication, whether it’s for the site owner to login, or for users to signup and use the application. With this in mind, it doesn’t make sense to rewrite a proven secure login system on every application you develop.
Secure password hashes
With the bcrypt library in place you can easily generate fairly secure passwords, certainly a lot better than sha1 or md5 could accomplish. More information on why you should use bcrypt for your hashes.
In short Bcrypt has been around for some time, attracted a lot of attention and yet still remains uncracked. The major benefit though is that you can tweak the amount of cycles of crypt, the more cycles, the stronger the hash. Bear in mind though this will have a detrimental effect on performance.
MY Controller
All of the controllers within the site will inherit a custom controller. With this setup there are 4 different controllers to choose from as standard.
- Base controller is the barebones controller where the shared methods and data is placed.
- Frontend controller is for any public facing front end site pages and thus doesn’t require a login.
- App controller is for the users section of the application itself and requires any user trying to access a controller that inherits this to be logged in.
- Admin controller is for the owners administration section and will not only check for login, but also that the user has admin privileges.
Models
For some applications that may not receive a large amount of traffic and thus don’t need highly optimised querys, I personally wouldn’t have a strong objection to using an ORM to help build rapid models… however for the most part I like to have things running super fast even if I will be the only user of the app. The custom MY Model takes care of the basic CRUD tasks and populates the model with data. When considering the data structure of the models I really wanted something that could directly be passed into json_encode to make dealing with JavaScript a lot easier, I therefore decided it was best to populate the models properties directly rather than have accessor methods for each instance variable and using __call to magically make get methods and set methods.
One thing I wanted to make sure though was the restriction of only setting and getting properties that exist in the defined array of fields in the models constructor. This will aid massively in some late night coding efforts when you might mistype a certain properties name. To accomplish this I made use of the __get and _set magic methods and checked if the objects property existed in the fields array.
Built in methods
- populate will take a query row or stdClass object and populate each of the required fields with the data passed to it.
- add will insert a new object into the database
- update will do the same as add only specifying an ID to change data in.
- delete is the one to look out for, there are no warnings or easy undo’s for deleting records, so just be careful you have the right confirmations in place.
- find will search for 1 particular record by the primary key and populate its object for you.
- find_where has to be a little more complex because multiple entries could be returned from the database call, therefore find_where shall just return an array of populated objects.
Error handling
I have made all errors work through Exceptions with try, catch blocks. One handy and conventional route I decided to go down was to extend the Exceptions class for each model (User_model - line 34) to allow multiple catch blocks based on Exception type. If you haven’t tried try catch and exceptions, I thoroughly recommend it, you will be able to debug your application a lot easier.
For my general purpose needs I am quite pleased with this implementation and think it will help with rapid development on most projects.
Wrapping up
I hope this is an inciteful overview of my default codeigniter setup and for those who are new to the framework might provide some inspiration. Leave any comments below on other tips or things you usually find yourself implementing in codeigniter (or whatever other framework you use).