Tuesday, January 18, 2011

CodeIgniter and Caching, a love hate relationship

As I am sure you have realized by now I am a huge fan of CodeIgniter. I find it amazingly easy to work with and feel that it really stays out of my way when I need it to. That being said one of its few weak spots is caching. Lets be clear I am talking about page caching now query caching which has its own short coming but in general can be useful.

Page caching in CodeIgniter is an all or nothing affair. Meaning that you either cache a full page or you don't cache anything. This might have been useful in the 90's when websites were far less interactive than they are today. However in the modern age of web design pages often have dynamic content that changes on a per user basis. For instance showing a users name at the top of a page when they are logged in, or providing an administration option if someone has the proper security clearance. These things would cause a page to look different from one user to the next. This simply isn't possible with the default implementation of caching, the last thing we need is having someone without clearance to be able to know more about our sites administration area.

Many people have written caching libraries for CI and I am sure there are some good ones. All of them lack the shear simplicity of CI's implementation, so here is my stab at it.

The name of this library is called scache for s(imple)cache it has one relatively small library file and a config file. If you would prefer you can combine the config file with CI's config file.

This library lets you cache whatever you need whether that be a full page or a small page segment. You define the unique key used to retrieve the cache file.

The library methods are as follows:


$this->scache->clear($key);
$this->scache->read($key);
$this->scache->write($key);


The clear method should generally be used to clear a cache file if you cannot wait for it to expire normally. Say for example you allow commenting on a page you obviously don't want your users to have to wait several minutes before they can view what they posted. Speaking of expiration, remember that config file I told you about? It only has a single line which defines how long to cache a file in minutes here are its contents:


$config['cache_expiration'] = 1;


Let's see this sucker in action now.


if(!$cache = $this->scache->read($key))
{
    //Build your view data array here
    //
    //
    //
    $cache = $this->load->view('page_segment', $data, true);
    $this->scache->write($key, $cache);
}
$this->load->view('full_page', array('segment'=>$cache));


Somethings to keep in mind looking at this implementation:
  1. The key value can be whatever you want, as long as it is always unique to that particular page segment. The key is how the library will name and find the cache file so it needs to be unique.
  2. In this setup I have a wrapper called "full_page". This file would include things like the main nav the logo the footer etc. Where as "page_segment" is only meant to contain something that will remain static like an 'About Us' paragraph or something.
  3. Remember the data contained in "page_segment" should not change between users or at least not change much.
Below is a link to a zip of both the library and the config file. Please let me know if you have any issues.

http://dl.dropbox.com/u/13081549/Scache.zip

Tuesday, January 4, 2011

Some CodeIgniter Constants

As a CI dev I am sure you have seen these before, and they are pretty useful once defined. The problem is that the CI docs don't really tell you what they are, and their names are only descriptive once you know what they do. To the new guy these may seem to have some kind of mystical powers.

Here is a link to the docs that outlines the constants listed below.
http://codeigniter.com/user_guide/general/reserved_names.html

The first constant is APPPATH (thats 3 'P's ). This variable is initialized in the root index.php file and is the path to the application folder of your CI installation. Pretty straight forward.

BASEPATH is the path to the system folder of you CI application. This is defined in the root index.php file.

CI_VERSION as I am sure it is obvious, is the version of CodeIgniter you are running.

DIR_READ_MODE, DIR_WRITE_MODE these values are used when dealing with files in CI. Namely when checking and setting read write modes of directories. These values reside in the constants config file of CI.


EXT refers to a file extension which would typically be ".php". This is defined in the root index.php file.

FCPATH is the full server path to the root index.php file. This is defined in the root index.php file.
FILE_READ_MODE, FILE_WRITE_MODE same as DIR_READ_MODE, DIR_WRITE_MODE except these deal with files instead of directories.

Next are a bunch of FOPEN constants which as the name implies deal with using fopen and popen in CI. These also reside in the constants config file if you want to take a peak at them.

SELF refers to the name of the root index.php file and usually has a value of "index.php". This is defined in the root index.php file.

Really the only constants that would be used with any kind of regularity are APPPATH and BASEPATH. The others are more involved in the internals of CI, but I am sure they are useful in some circumstances.

Hopefully that gives you a better idea of what these suckers do.