Rapid Application Development with CodeIgniter

by: Akash Mehta

Why should you be using CodeIgniter?
There's a lot of choice for PHP frameworks out there. A quick look at this list reveals quite a few options, each with advantages and disadvantages. Many frameworks offer ORM, or Object-relational Mapping; some offer authentication systems or AJAX interfaces inbuilt. Chances are, however, that you just want to get on with coding, and don't want to have to deal with complex libraries. CodeIgniter achieves this wonderfully, staying out of your way but offering a lot of functionality if and when you need it.

MVC 101

In a framework-less PHP application, you'll typically have a number of seperate PHP scripts, each of which is accessed directly by the client. There might be a global header and footer, possibly with some standard functionality for database access. There are a number of problems with this approach, however, including inconsistent application entry points, repetition of code for standard tasks and so on. As the application grows, it can also become very inconsistent and hard to maintain.

The MVC design pattern goes a long way towards solving this. In MVC, your application is split into three parts - the Model, the View and the Controller. The Controller controls application flow and routing, handing off requests to other parts of the application. The Model manages data related to your application. Finally, the View represents the interface to your application, in this case our HTML front-ends. Views can contain basic logic, but most complex routines lie in the model.

The one problem with MVC, however, is that all this clean seperation is only effective if you observe it. You should start with the basic purpose of each section. For example, never access the database in your controller or view - that's what the model is for. Never output HTML in your controller or model, leave it to the view; and certainly never handle redirects within your view.

Still, here's what you should do. Your views can (and probably should) contain basic loops and simple if logic. Views should be where output is constructed, with only the bare essential data passed to them. Controllers can (and should) be full of all the business logic your application needs, and models should process data as needed without worrying about output. Keep this in mind and you should get a lot out of using MVC for your application.



Introducing CodeIgniter!

Before we delve into the internals of CodeIgniter, let's have a look at a quick sample of how it works. Grab a copy of CodeIgniter from CodeIgniter; I'll be working with version 1.6.1 in this example.

Let's say we have a very basic application that takes a name via the URL and writes out, "Hello $name!". Here's how we would build it in just PHP, and then in PHP with CodeIgniter.

Raw PHP

index.php:
<?php
$name = $_GET['name'];
if (!$name) die('No name supplied.');

echo '<html>';
echo '<body>';

echo 'Hello, '.$name.'!';

echo '</body>';
echo '</html>';
?>

Not exactly the best PHP script ever, but it should do for our demonstration.

CodeIgniter

CodeIgniter enforces consistent and effective file seperation from the ground up, with a simple filesystem structure as part of their implementation of MVC. The system/application folder has subfolders called 'controllers', 'models' and 'views'.

system/application/controllers/hello.php
<?php
class Hello extends Controller {
function index($name) {
$data['name'] = $name;
$this->load->view('show_name', $data);
}
}
system/application/views/show_name.php
<html>
<body>
Hello, <?=$name?>!
</body>
</html>

Here you can see we have two seperate files, which, as you might have guessed, are the controller and view. The controller is entirely OOP; the index() method is called automatically when the user visits. The view file is almost entirely HTML, using alternative syntax to display the $name variable, which is drawn from the 'name' element of $data passed to $this->load->view(). Every element of $data is made available to the view as a variable of the same name. In this way, you can consistently pass data between your controller and view.

Notice that the view looks much cleaner than the echo calls we used earlier. Sure, you could jump in and out of PHP for that small example; maybe you only need one line of code to achieve the same functionality. Now, if your application is that simple and you aren't worried about XSS vulnerabilities, it's okay. However, our CodeIgniter version is better prepared to increase in complexity, with clean seperation between the business logic and the presentation. When we extend this in future, we can easily modify the frontend or the backend (or both) while making it easy to keep track of everything.

Anyway, in this example, our controller class Hello is extending the CodeIgniter class Controller giving it access to the framework core. This includes functionality for input filtering, the library for which is loaded at $this->input. By passing an optional parameter to $this->load->view(), we provide it with data to make available to our view. Our view then displays this data.

If I point my browser to http://localhost/ci/index.php/hello/show_name/Akash/, sure enough, I see the text "Hello, Akash!" on the screen. Now, the URL isn't pretty. With a simple .htaccess file (the directives for which are available in the CodeIgniter manual), we can remove the index.php. With a quick routing hack we can also remove the hello. Finally, we can rename index to something more appropriate - how about show_name? With a few quick changes, I now have a CodeIgniter-based MVC web application (albeit one lacking in any useful functionality) available via http://localhost/ci/show_name/Akash.

Just a note on URLs: when you drop CodeIgniter into your website, it takes over as the application entry point (from its root installation directory, e.g. ~/public_html/ci) . From now on, your URLs will look something like http://example.com/index.php/hello/show_name/Akash. In this example, CodeIgniter takes apart the URL and routes it accordingly, working out that Hello is the name of the class (note: class names start with a capital), it should call the show_name() method within the object of that class, and pass the value 'Akash' as the first parameter to the method. You can have as many parameters as you like, just adding them on the end, seperated with /'s. Therefore, your URLs look something like http://example.com/index.php/controller/method/param1/param2/param3. The index.php can easily be taken out using .htaccess files and mod_rewrite. More on this in the manual.

Notice the framework also handles clean search-engine-friendly URLs for us. Oh, and the glaring XSS vulnerability in our pure-PHP example earlier? Try putting anything vaguely harmful into the URL and CodeIgniter will reject it. It's XSS-proof already, with not a single input validation routine in sight. We've barely started and already CodeIgniter is making our life easier.



Getting our feet wet

As an example to introduce you to CodeIgniter, we're going to build a simple job board. Jobs will be pre-populated in a database table called 'jobs'. There will be two pages - a list of available jobs, and a detailed summary page for each job. So, without further ado, let's get into it!

Setting up CodeIgniter

You'll need an Apache-powered PHP+MySQL server for these examples. First, download CodeIgniter. Extract it into your web directory under a subfolder; I recommend /ci to help following along, but it doesn't really matter. We won't tackle environment tweaks, but rather demonstrate the power of CodeIgniter and how you can use it.

Open up system/application/config.php in your CodeIgniter folder. It's pretty self explanatory, and is wonderfully commented too. You'll need to set $config['base_url'], and, well, that's about it. Fire up your web browser and point it at the location of your CI installation and you should see a welcome page with a few basic instructions.

We'll also have to configure database access. open up system/application/database.php and scroll to the bottom. You probably only need to edit these entries:

system/application/config/database.php
$db['default']['hostname'] = "localhost";
$db['default']['username'] = "";
$db['default']['password'] = "";
$db['default']['database'] = "";
...

CodeIgniter helps you quickly move code between servers with different database configuration details. The 'default' here refers to the active configuration group, defined a few lines above in $active_group. This also makes connecting to multiple databases on different servers easy. Check out the manual for more details. Make sure the database you specify exists; you may want to use a table name prefix if you want/need to use an existing database, in which case set $db['default']['dbprefix'] to something like citest_.

Planning our application

We're going to keep it simple here. Most frameworks like to demonstrate with a blog system; we won't even go that far, but once you've finished reading through this, CodeIgniter has quite a nice collection of video tutorials. For our job board, we'll have one controller, one model and two views. The controller will handle both the main job list and the job summary pages, with a model method and view for each. In this way, we'll clearly seperate the different parts of our application.

Just a note on CodeIgniter naming conventions: all file names are lower case, all class names start with an uppercase letter and are in files of the same name (plus the .php extension). CodeIgniter does alter the capitalization of names you pass to it, so under_scores are used as opposed to StudlyCaps or camelCase.

The controller

As we briefly covered before, a controller is basically a class with a few methods that handles incoming requests and directs them accordingly. The class extends CodeIgniter's Controller class, and in doing so gains access to all the functionality of the framework. In our controller, we'll load the various resources we're going to need - specifically, a model and some views. None of this, especially the model, is loaded by default - CodeIgniter is designed to run very lightweight. The object at $this->load provides a system for loading such resources, as we'll see in a moment. Here's the code for the controller:

system/application/controllers/jobs.php
<?php
class Jobs extends Controller {
function index() {
// This gives us redirect()
$this->load->helper('url');
redirect('jobs/list_jobs');
}

function list_jobs() {
$this->load->database();
$this->load->model('jobs_model');
$data['jobs'] = $this->jobs_model->get_jobs();

// This gives us anchor() - see the view at the end
$this->load->helper('url');
$this->load->view('jobs_view', $data);
}

function view_job($id = false) {
$this->load->helper('url');
if (!$id) redirect('jobs/list_jobs');

$this->load->database();
$this->load->model('jobs_model');
$data['job'] = $this->jobs_model->get_job($id);

$this->load->view('job_view', $data);
}
}

As you can see, the controller is fairly simple, merely taking input, fetching data from the model and sending it to the view. We start the bulk of each routine with $this->load->database(), which will connect to the database and prepare the database interface library for us using the settings we defined earlier. Then we initialise our model.

This is CodeIgniter's approach to models - $this->load->model('classname') will load up the file at system/application/models/classname.php and initialise an instance of the class Classname within the file (you shouldn't really include other files). It will then put a reference to the new object at $this->classname. You can override this particular behaviour by passing a second argument, a string, to be used as the property name for the object. For example, you could call $this->load->model('someclass', 'data'); and access the model class at $this->data instead of $this->someclass . So, now that we're already making use of our wonderfully non-existent models and views, let's actually create them!

The model

We haven't actually covered a model yet. Similar to controllers, they extend the Model class. Once the database is initialised, through a call to $this->load->database(), they have access to the extensive database class of CodeIgniter.

As you saw in our controller, our model will have two methods, one to fetch all jobs in the database - get_jobs() - and one to fetch details for a particular job - get_job($job_id). There is no particular naming convention for models, however I typically use the controller name with a _model on the end. It's either this or you pick a different name entirely - CodeIgniter isn't magical, and it can't help you load two classes with the same name.

The CodeIgniter manual has an excellent quick start guide for the database library that you should read through before proceeding. Here's the code for our model:

system/application/models/jobs_model.php
<?php
class Jobs_model extends Model {
function get_jobs() {
$query = $this->db->get('jobs');
foreach ($query->result_array() as $row)
{
$result[] = $row;
}
return $result;
}

function get_job($job_id) {
$query = $this->db->where('id', $job_id)->get('jobs');
$result = $query->row_array();
return $result;
}
}

Let's take a moment to examine this, as it's probably the most complicated section of the tutorial. CodeIgniter has an (optional) Active Record class that allows developers to access their databases in an Active Record-style manner. You can write your own raw SQL queries and pass them to $this->db->query(), but there are a number of advantages to using the Active Record class, not the least of which is CodeIgniter will handle your table prefixes for you. Take a sample SELECT * FROM table WHERE id='0' query. Using the Active Record class, you would write it like this:

$this->db->select('*')
->from('table')
->where('id', '0')
->get();

Notice we're using PHP5's method chaining - calling the select() method, then the from() method, and finally the where() method. Each of these methods returns $this in their own context - i.e. when you call them you get back what you called them from; in this case, $this->db.

Our get() method is important, as it's the one method (besides getwhere(), which we won't cover here) that ends the query. When called, it tells the database library to construct the SQL query based on the information passed in already (where information is missing, it makes assumptions, all the way to a standard SELECT * FROM 'table', where supplying 'table' is compulsory). It then runs the query against the database and returns a query result object. We can manipulate this object easily, such as fetching a row array using the result_array() method. The row_array() method is similar except it will only ever give us a single result row.

So, with that taken care of, we have succesfully fetched data from our database. But wait! We don't yet have a database table! Run this query against your database, substituting table name as appropriate:

CREATE TABLE `jobs` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,
`title` TEXT NOT NULL,
`company` TEXT NOT NULL,
`description` TEXT NOT NULL
);

This will create a very basic table to store our job data in. Populate it with some sample rows - be creative and come up with some job postings you'd like to see. The table structure isn't meant to be at all representative, and a live job database would have far more data for each job record, however as we don't need any more data to demonstrate CodeIgniter we'll stick with this. Finally, we now have a database layer and some actual data to send through it! Now, on to the view!

The view

This is the final stretch - the presentation of your application. We've taken all the data we need from the database, and we've passed it to our views to be ready. These views won't be pretty - in fact, they may not even be HTML valid - but they're just to demonstrate the basics of MVC in CodeIgniter, so please bear with me here. Let's start with the standard job view.

Now, our view is going to be called jobs_view. We decided this when we coded this line of our controller:

$this->load->view('jobs_view', $data);

This basically tells CodeIgniter to load up the view at system/application/views/jobs_view.php, and to take the associative array $data and create a variable available within the view for each element, e.g. $data['jobs'] would give us a $jobs variable - and that's exactly what happens. Let's print_r($jobs) to see what we're working with first. Create this jobs_view.php file and put a <?=print_r($jobs)?> in it. You should see something like the following:

Array
(
[0] => Array
(
[id] => 1
[title] => Web Developer
[company] => Google
[description] => Develop kick-ass web applications
for the mighty Google.
)

[1] => Array
(
[id] => 2
[title] => Sr. Web Developer
[company] => Ellis Lab
[description] => Help the world develop kick-ass web
applications with our software.
)

)

Now, maybe you could have got to this stage quicker with simple mysql_query() and mysql_fetch_array(), but as you extend your application you'll definitely find the framework approach easier and more efficient. In any case, now that we have our array, manipulating is almost self explanatory. We'll use a basic slightly-styled table.

system/application/views/jobs_view.php
<html>
<body>
<table border="1" style="border-collapse: collapse;">
<thead>
<tr>
<th>Job Title</th>
<th>Company</th>
<th>View</th>
</tr>
</thead>
<tbody>
<?php foreach ($jobs as $job): ?>
<tr>
<td><?=$job['title']?></td>
<td><?=$job['company']?></td>
<td><?=anchor('jobs/view_job/'.$job['id'], 'View')?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</body>
</html>

All pretty simple stuff, and very standard PHP. Our final view, for individual jobs, is even easier:

system/application/views/job_view.php
<html>
<head>
<h1>Viewing Job: <?=$job['title']?></h1>
<p><strong><?=$job['company']?></strong></p>
<p><?=$job['description']?></p>
</head>
</html>

And there you have it! A database driven PHP web application built on CodeIgniter. Load up http://localhost/path/to/codeigniter/index.php/jobs/list_jobs and you should see something like this:



Further CodeIgniter
If you enjoyed this tutorial and you're interested in CodeIgniter, you should definitely take 15 minutes to run through the video tutorials on the official website. The blog tutorial is an excellent demonstration of what CodeIgniter can do in practice, making use of the various features of the framework; in this tutorial, we've only really touched upon the basics of the MVC implementation. The wiki is also an excellent destination for further reading - this page has a good list of topics you can choose from - although the content there can be a little complex and is not designed for the novice user (yet!).

Article published Sunday, 17th February 2008
© 2008 NetVisits, Inc. All rights reserved.