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.

First, the code, place it in the libraries folder and name the file 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]

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

now for usage, this happens inside the view: [code] <?php // some un-cached code // some more un-cached code

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

// even more un-cached code [/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