Archive for June, 2009

How to setup CodeIgniter

Introduction

This article explains the process I go through to setup the CodeIgniter framework and how to configure it so that I can start developing an application.

What is CodeIgniter?

If you don’t already know, CodeIgniter is an MVC framework built on PHP.  There are many features and built in functions that make building a web application fairly easy.  You can download the current version, 1.7.1, from CodeIgniter.com.  Also, check out the very well documented User Guide.

If you are interested in using the Zend library of tools with CodeIgniter, please check out How to use Zend_Search_Lucene with CodeIgniter.

Step-By-Step

For this tutorial, I’m using a WAMP Server running on my local Windows computer.  You could just as easily perform these same actions on a web server running PHP, although the paths may be different depending on if you are using Windows or a Linux based server.

Step 1

Download the latest version of CodeIgniter (1.7.1).

Before extracting the files to your server, let’s talk about where to put the files.  For security purposes, it is recommended to place the CodeIgniter files outside the path of your web server so those files cannot be accessed by typing in a URL.  So, if I access my web server by typing in http://localhost and the web server loads the website at C:\wamp\www\, then I want to place the System folder of CodeIgniter inside the C:\wamp\ folder.  Go ahead and extract the System folder from the download package to the C:\wamp\ folder.  You can place the System folder in the C:\wamp\www\ folder if you desire.  Just make sure to adjust the path name later on.

Step 2

Next, I have decided that I may want to use CodeIgniter for several applications that I develop.  To save on hosting space, I can setup all CodeIgniter applications to use the same core framework.  First, we need to move some files around from their default locations.

Open the C:\wamp\system\application\ folder.  You should see several folders listed here.  The default CodeIgniter application is setup for a single application.  We will be changing it to run multiple applications.  Create a new folder called baseApplication_1234 or something unique.  Make a copy of the index.html file and paste it inside baseApplication_1234.  Next, move all of the folders located at C:\wamp\system\application\ into C:\wamp\system\application\baseApplication_1234\.

We will configure this base application with all of our default settings that we want to use for all CodeIgniter applications.  Then, when you want to make a new application, you can simply copy the baseApplication_1234 and rename it.

Step 3

Next, we will configure the CodeIgniter application files.

Browse to C:\wamp\system\application\baseApplication_1234\config\ and open the following:

autoload.php

Modify line 42 to show:

$autoload['libraries'] = array('database', 'session');

 config.php

Modify line 14 to show (change localhost to your domain name):

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

Modify line 26 to show:

$config['index_page'] = "index.php?";

This line will be very important for the way our URLs are displayed later on.

Modify line 44 to show:

$config['uri_protocol'] = "QUERY_STRING";

Modify line 57 to show (this is optional if you want a .html to be shown on the end of your URLs):

$config['url_suffix'] = ".html";

Modify line 220 to show (add your own unique value within the quotes):

$config['encryption_key'] = "12345";

Modify lines 234 – 241 to show:

$config['sess_cookie_name']  = 'ci_session';
$config['sess_expiration']  = 7200;
$config['sess_encrypt_cookie'] = TRUE;
$config['sess_use_database'] = TRUE;
$config['sess_table_name']  = 'ci_sessions';
$config['sess_match_ip']  = TRUE;
$config['sess_match_useragent'] = TRUE;
$config['sess_time_to_update']  = 300;

This will require that we have a database and a table within called ci_sessions.  This table will need to have certain fields that CodeIgniter will be attempting to write session data to for each users who visits your site.  I’ll explain more later on.

database.php

Modify lines 41 – 45 to show:

$db['default']['username'] = "dbuser";
$db['default']['password'] = "mypassword";
$db['default']['database'] = "mydbname";
$db['default']['dbdriver'] = "mysql";
$db['default']['dbprefix'] = "dev_";

You will need to enter your correct username, password, database name, and prefix if you wish to use one.  If you use a prefix, you will need to have a table called dev_ci_session instead of ci_session.

routes.php

For the base application, the routes.php file is probably OK.  There are two lines that need to be modified when you build an application. 

$route['default_controller'] = "welcome";
$route['scaffolding_trigger'] = "12345";

Again, use some unique value for the scaffolding_trigger.  If you use a value that is hackable or nothing at all, your application will have a possible security hole.  The default controller name can be changed here as well.

Step 4

There are two helper files that I add to my projects that help translate the URLs the way I like them (http://localhost/controller/action/id.html).

MY_form_helper.php


<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
if ( ! function_exists('form_open'))
{
    function form_open($action = '', $attributes = '', $hidden = array())
    {
        $CI =& get_instance();

        if ($attributes == '')
        {
            $attributes = 'method="post"';
        }

        //Modify ->site_url to ->item('base_url').$action
        $action = ( strpos($action, '://') === FALSE) ? $CI->config->item('base_url').$action : $action;

        $form = '<form action="'.$action.'"';
 
        $form .= _attributes_to_string($attributes, TRUE);
 
        $form .= '>';

        if (is_array($hidden) AND count($hidden) > 0)
        {
            $form .= form_hidden($hidden);
        }

        return $form;
    }
}
?>

MY_url_helper.php


<?php
function redirect($uri = '', $method = 'location', $http_response_code = 302)
{
    $CI =& get_instance();

    switch($method)
    {
        case 'refresh' : header("Refresh:0;url=".site_url($uri));
        break;
        default   : header("Location: ".$CI->config->item('base_url').$uri, TRUE, $http_response_code);
        break;
    }
    exit;
}
?>

Create these files and save them to C:\wamp\system\application\baseApplication_1234\helpers\.  These functions will override the original CodeIgniter functions and fix some URL rewriting issues.

Step 5

Enabling URL rewriting may depend if your server supports it.  Apache has a rewrite_module that must be enabled before this will work.  Most hosting providers should already have enabled URL rewriting.

Create a new text file called .htaccess and paste the following code into it:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?$1 [L]

This will redirect all requests on your domain back to the index.php file, unless the actual path does happen to exist, then the server will serve up whatever file/directory is at that location.

Notice the ? behind index.php.  The web server is rewriting the pretty URL into a QUERY_STRING that CodeIgniter is expecting and passes in the controller and action as variables such as index.php?var1=this&var2=that. 

The .htaccess file should be stored in the C:\wamp\www\ folder or the root of your web site.

Step 6

Next, the database will need to be created and the ci_sessions table created to store the user sessions to.

After you create the MySQL database, run the following SQL and it will create the table for you:

CREATE TABLE `dev_ci_sessions` (
  `session_id` varchar(32) NOT NULL,
  `ip_address` varchar(15) NOT NULL,
  `user_agent` text NOT NULL,
  `last_activity` datetime NOT NULL,
  PRIMARY KEY  (`session_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

Make sure to remove the “dev_” if you did not setup a dbprefix.

Step 7

Next, for testing purposes, we’ll setup the baseApplication_1234 web application and attempt to run it.

Find the index.php file that came with the CodeIgniter 1.7.1 download.  It should be located in the same folder as the system folder and user_guide folder.  Copy this file into your web site root at C:\wamp\www\.

Modify line 26 as shown:

$system_folder = "c:/wamp/system";

Modify line 43 as shown:

$application_folder = "application/baseApplication_1234";

This is the line that specifies which application to load.

This index.php file is the main entry point for the application.  It will use these modifications to find the C:\wamp\system\ folder and run the correct web application.  The only other files that need to be in the C:\wamp\www\ folder are files that HTML needs to be able to access via URLs such as images and JavaScript.

Conclusion

That should be everything.  You can now try to open your web application by going to the URL, http://localhost.  The default controller is Welcome and the default action is Index, so you can also test http://localhost/welcome/index.html to verify URL rewriting works.  Remember the “.html” can be used to hide that PHP is running your web site.  In reality, index is an action of the welcome controller and doesn’t need the “.html” to be there at all.

If you run into problems, you can add this line to an action or the controller’s constructor for further information:

$this->output->enable_profiler(TRUE);

Be sure to shut this down when not needed, or it could give your users information you may not wish them to have.

Understanding Polymorphism

Introduction

This article will explain what polymorphism is and how it can help you design and reuse code in Object-Oriented Programming.  You’ll learn what polymorphism is and how to use it.  In the following examples, I’ll be using Visual Basic .NET, but any language that supports Object-Oriented Programming should be able to use these same techniques.

If you have not already read the articles on Understanding Objects and Understanding Inheritance, please check them out as some of the terms and other information explained there will be used in this article.

What is Polymorphism?

According to dictionary.com, the definition of Polymorphism is as follows:

3. Biology The occurrence of different forms, stages, or types in individual organisms or in organisms of the same species, independent of sexual variations.

So, how does this relate to programming?  We’ll develop Objects that have different forms of the same “species”.  The great thing about Polymorphism is that when you are building your program, you assume you are working with the “species” Object, but you actually use an individual “organism” Object.  This allows the “organism” Objects to be exchanged in the code for one another.

In other words, say we have a Parent Class called Animal and two Child Classes that Inherit from Animal called Cat and Dog.  The Cat and Dog are both Animals, so they will inherit all the properties and methods that an Animal has.  If we wanted to store an array of Cats or Dogs, we could just declare the array to be of type Animal and then we’d be able to store either Cats or Dogs within the array.  That is Polymorphism.

Parent Classes and Interfaces

Both Parent Classes and Interfaces can be used to setup an Object as the “species” level.  Parent Classes have been explained in Understanding Inheritance.

What is an Interface?

An Object’s Interface is how you communicate or interact with that Object.  Interfaces in programming terms are similar to a Class Object, but an Interface does not implement the properties or methods it declares, it simply declares them.

Why is this useful?  Interfaces force the Class Objects that implement the Interface to have all of the properties and methods of the Interface.  So, the following IAnimal Interface could be implemented by Cat and Dog to force them to implement the properties, Height and Weight, along with the methods, Eat and Drink.

Public Interface IAnimal

    Property Height() As Integer
    Property Weight() As Integer

    Function Eat(footType As String) As Boolean
    Function Drink(drinkType As String) As Boolean

End Interface

Interfaces can be used with Parent or Child classes and multiple Interfaces can be used by one Class.  Also, in some cases, you may want to use an Interface in place of a Parent Class, forcing all properties and methods to be fully implemented in each class.  Another thing to keep in mind is that a Parent Class that implements the IAnimal Interface does not have to fully implement all properties and methods.  Instead, the Parent Class could implement those common properties or methods that will not change no matter the Child Class, and leave the others to be implemented by the Child Class.  In VB.NET, you can use the MustOverride keyword on the function declaration.  This will make the Parent Class an Abstract class.

Public MustInherit Class Animal Implements IAnimal

    'Data Members.
    Private _height As Integer
    Private _weight As Integer

    Public Property Height() As Integer Implements IAnimal.Height
        Get
            return _height
        End Get
        Set(ByVal Value As Integer)
            _height = value
        End Set
    End Property

    Public Property Weight() As Integer Implements IAnimal.Weight
        Get
            Return _weight
        End Get
        Set(ByVal Value As Integer)
            _weight = Value
        End Set
    End Property

    'Abstract Functions.
    Public MustOverride Function Eat(foodType As String) As Boolean Implements IAnimal.Eat
    Public MustOverride Function Drink(drinkType As String) As Boolean Implements IAnimal.Drink

End Class

 Now, things are looking pretty good.  We can force are Classes to implement certain properties and methods, but there is still one downside.  Our methods are passing in a String value for foodType and drinkType.  What if we wanted to use a different data type, such as our own Object that holds other properties for foodType?  We don’t want to have to modify the Interface or Parent Class each time this may change.  What we want to do is make the Class or Interface Generic.

How do I make my Interface or Class Generic?

Making a Class or Interface Generic will make your code more reusable.  When you make a Class or Interface Generic, you don’t have to know what type of data you will be using with the Object until you declare or create an instance of the Object.  So, various programs could use the same Class Object, but passing in different data types to work with when instantiating the Object. 

Public Interface IAnimal(Of T)

    Property Height() As Integer
    Property Weight() As Integer

    Function Eat(foodType As T) As Boolean
    Function Drink(drinkType As T) As Boolean

End Interface

T is a place holder for the type of data we will declare later on.  Notice in the declaration of the Interface and both methods, Eat and Drink, T is used.  Now, when we create a Cat or Dog using the IAnimal Interface, we can determine what type of data will be used for foodType and drinkType.

Public Class Cat Implements IAnimal(Of String)

This would declare a Cat to use a String data type to store the foodType and drinkType.

Public Class Dog Implements IAnimal(Of Integer)

And this one would declare a Dog to use an Integer data type to store the foodType and drinkType.

We could also define our own complex Class Object as the data type.

Advantages of using Polymorphism, Interfaces, and Generic Objects

  • Polymorphism allows you to use similar types of data together.  It also can be used to improve system maintenance, reuse code, and easily setup testing Objects that mimic communications with databases and other resources.
  • Interfaces force the implementation of properties and methods on Objects that implement the Interface.
  • Generic Objects allow more reusable code when building Class Objects and Interfaces.

Understanding Inheritance

Before we get started on the topic of Inheritance, please check out Understanding Objects.  Now, onward…

According to dictionary.com, one definition of inheritance is:

2. the genetic characters transmitted from parent to offspring, taken collectively.

This definition also fits with Object Oriented Programming.  Remember, that our Objects mimic those found in real-life and just like in real-life, Objects can have Parent Objects or Children Objects.  Inheritance is the process of obtaining the properties and methods from another Object.  The Child Object inherits these properties and methods from the Parent Object.

Using Inheritance, we can extend the functionality of a Class Object without having to modify that Object.  This helps you make your own code more reusable as well as gives you the ability to improve other people’s Class Objects.

Access Modifiers

I had talked breifly about Access Modifiers in Understanding Objects.  When building Parent and Child Class Objects, you will most likely be using all three: Private, Public and Protected.

A Child Class that inherits from a Parent does not gain access to all of the Parent’s properties and methods.  The Parent uses Encapsulation and Data Hiding to protect it’s Private properties and methods.  The Child Class can only access those properties and methods that are Protected or make up the Public Interface for the Parent Class.

The Protected access modifier acts similar to Private, keeping the properties and methods hidden from outside use, but it will allow Child Class Objects access to them.

Below is an example of a Parent Class:

Public Class MyParent

    Private _hiddenVariable As String
    Private _errors As String

    Public Sub New()

        _hiddenVariable = “”
        _errors = “”

    End Sub

    Protected Sub AddError(error As String)

        _errors += error + VbCrLf

    End Sub

    Public Function GetErrors()

        Return _errors

    End Function

End Class

Below is an example of a Child Class:

Public Class MyChild
    Inherits MyParent

    Public Sub New()

        MyBase.New()

    End Sub

    Public Function MyNewFunction()

        Return "It Worked!"

    End Function

End Class

In the above examples, the Parent Class has a couple Private string variables.  The subroutine, AddError, would normally be a Private function, but since we want the Child Class to have access to this function, we must change it to Protected.

There are two methods on MyParent’s Public Interface: New() and GetErrors().

The MyChild Class uses Inheritance to extend MyParent’s functionality.  In VB, the Inherits keyword is used to tell which class is the Parent.  Within MyChild, all of the functions on the Public Interface for MyParent as well as the Protected function, AddError, can be accessed.

There are three methods on MyChild’s Public Interface: New(), GetErrors(), and MyNewFunction().

Overriding Methods

When developing a Child Class, you may find that you need to change the way that one of the Parent Class’ methods work.  To do this, you must override the method in the Child Class.  When an instance of the Child Class is used, the overridden function would be used within the Child Class instead of the Parent Class.

Some languages allow you to override the function by simply declaring the same function in the Child as in the Parent.  In VB, you would use the Overrides keyword to declare you are overriding a function.

Protected Overrides Sub AddError(error As String)

    _errors += "MyChild:" + error + VbCrLf

End Sub

This subroutine would be placed in the MyChild Class and would override the AddError subroutine found in the MyParent Class.  Errors that occur in the Child Class would show “MyChild:” in front of them.

Also, the Child method that overrides the Parent, can also call the Parent’s method.  This allows you the power of performing some small change without having to re-implement the entire method in the Child Class.  In VB, you would use the MyBase keyword to signal you are looking for the Parent Class version of the method.

MyBase.AddError("my error")

Abstraction

Abstraction is the process of declaring a Class, property or method without giving the details on the implementation of that element.  A Parent Class can use Abstraction to declare that a function must be present in any Child Class of that Parent.  The Child Class can then either define what the method does or declare the method as Abstract also.

If a Class is Abstract, then an instance of that Class can not be created.  You must instead, access the Class through one of it’s children. 

In VB, you can force a Class to be Abstract by using the MustInherit keyword.

Public MustInherit Class MyParent

Below is an example of the MyParent Class if we wanted to make the AddError function Abstract. 

Public Class MyParent

    Private _hiddenVariable As String
    Private _errors As String

    Public Sub New()

        _hiddenVariable = “”
        _errors = “”

    End Sub

    Protected MustOverride Sub AddError(error As String)

    Public Function GetErrors()

        Return _errors

    End Function

End Class

Advantages of Inheritance, Abstraction, and Overriding Methods

  • Inheritance helps you extend the functionality of your own classes or other people’s classes.
  • Abstraction can be useful if you need multiple Classes that have similar properties and methods.  You can create an Abstract Parent Class with the common properties and methods and have the Children Classes hold the unique properties and methods.
  • Overriding Methods allows you to change the functionality of a Parent Class without modifying the Parent’s code.

Understanding Objects

Objects are all around us; the monitor your looking at, your IPod, your cat or dog, etc.  Programming objects mimic those found in real life.  When you use an object, like an IPod, there are certain things you can do with it.  The object has an Interface, or way for you to interact with the object.  The object also has properties that work internally that you do not have direct access to, such as the current song playing, the next song to play, the current play position, etc. 

Programming Objects store the state of an Object in internal variables and has methods that are used to access that information.

Access Modifiers

Access modifiers let you set the access level of class properties or functions.

  • Private – Only this class’ functions can use the item.
  • Public – This class’ functions and any outside source can use the item.
  • Protected – This class or any Child Class can use the item.

Encapsulation

ObjectDiagramIn Object-Oriented Programming, your Class files have internal data members, or variables.  These variables hold properties of the Object.  By setting your Class variables to Private or Protected, you ensure that anyone using your Class cannot access the data directly.  If the variable needs to be accessed outside the Class, then Get or Set functions can be setup to allow access.  This ensures that your Class’ data cannot be changed without your knowledge.  This is called Encapsulation and allows for Data Hiding.

Imagine a radio Object in the example on the right-side where the two Class variables (in green) are Encapsulated in the object and surrounded by the Public Interface (in blue) to those variables.

One of the benefits of using Get and Set functions to access your Class variables is that you can do some validation to make sure the data is valid before storing it.

Public Interface

Each object, or Class file, you create will have a Public Interface that allows your program, or other classes, to communicate with it.  By using the Public access modifier, you allow anyone who creates an instance of your Class to access that Class variable or function.

Advantages of Object Oriented Programming

  • OOP creates a natural structure to your code mimicking real-world examples we can see.
  • Code that deals with an Object is grouped together making it easier to reuse and maintain.
  • Encapsulation allows for greater control over what variables can store.

New Theme And Other Changes

BiohazardI decided to update the site’s theme again.  I was already growing tired of the old one.  The site looks cleaner due to the spacing and fonts used.

I’ve also added some new items:

1) a code highlighting plug-in to make code snippets more visible.
2) a tag cloud box.
3) a website links box where I can list some of my commonly used websites.