Skip to content

Fragment Caching Library

World Wide Web Server edited this page Jul 4, 2012 · 16 revisions

Category:Libraries::Caching

[h3]Introduction[/h3] Ok, here goes: this is a library to add page-fragment caching capabilities to codigniter. That is: allow you, the programmer to mark a part of a view to be cached independently of other bits of the page. The idea is pretty simple, but I wanted the syntax to be as lean as possible, and to make usage as transparent as possible.

Usage: fragment caching is invoked via start/end markers in the view.

[code] // some un-cached markup & code // some more un-cached markup & code

<? if($this->cache_fragment->start(1)){ ?> // stuff you wish to cache <? } $this->cache_fragment->end();?>

// even more un-cached markup & code [/code]

The library: Place it in libraries/Cache_fragment.php

[code] <?php // Fragment caching library for CI // ============================================================================= // written by nir gavish 2010 // [email protected] // http://www.webweb.co.il/ (hebrew site) // ============================================================================= class Cache_fragment{ private $fragment_path = './cache/fragment/'; // make sure this is a valid dir private $fragment_name; private $newly_cached = false; private $CI;

function Cache_fragment(){
    $this->CI =& get_instance();
}

function start($lifespan){
    if ($this->fragment_name!=''){die('Nested fragment cache not supported.');}
    $x = debug_backtrace();

    $this->fragment_name = md5($this->CI->uri->uri_string().'||'.$x[0]['line']);

    // if file does not exist, make preparations to cache and return true, so segment is executed
    if(!file_exists($this->fragment_path . $this->fragment_name)){
        $this->newly_cached = true;
        ob_start();
        return true;
    }else{
        // cache exists, let's see if it is still valid by checking it's age against the $lifespan variable
        $fModify = filemtime($this->fragment_path . $this->fragment_name);
        $fAge = time() - $fModify;
        if ($fAge > ($lifespan * 60)){
            // file is old, let's re-cache
            $this->newly_cached = true;
            ob_start();
            return true;
        }
        // no need to redo
        return false;
    }
}

function end(){
    if($this->newly_cached==true){
        $new_cache = ob_get_clean();
        
        $fname = $this->fragment_path . $this->fragment_name;
        $fhandle = fopen&#40;$fname,"w+"&#41;;
        $content = $new_cache;
        fwrite($fhandle,$content);
        fclose($fhandle);
    }
    include $this->fragment_path . $this->fragment_name;

    $this->newly_cached = false;
    $this->fragment_name = null;
}

} ?> [/code]

Of course, you can either add 'cache_fragment' to the autoload, or do: [code]$this->load->library('cache_fragment')[/code]

[b]Note[/b]: The number fed to the ->start(x) function is the expiration time of the cache in minutes.

[b]Note2[/b]: The name of the cache is derived from the full URL + the line number that called the cache, that way, multiple caches may exist on the page, each kept in a separate cache-file, with separate expiration times, this is probably the only semi clever bit in this library.

[b]Note3[/b]: Nested fragment caching is not supported, because I'm lazy, if anyone really, absolutely needs it, I'll sit down and add the feature.

[b]Note4[/b]: Contact me with anything, really

Clone this wiki locally