Part of the EllisLab Network
x
 
Create New Page
 View Previous Changes    ( Last updated by huzzi )

Fragment Caching Library

Contibutors:Libraries -> Caching

Introduction

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.

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

<? if($this->cache_fragment->start(1)){ ?>
  
// the argument in function 'start' is the cache's expiration time in minutes
  // stuff you wish to cache
<? } $this->cache_fragment->end();?>

// even more un-cached markup & code 


The library: Place it in libraries/Cache_fragment.php

<?php
// Fragment caching library for CI
// =============================================================================
// written by nir gavish 2010
// nirg@tantalum.co.il
// 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($fname,"w+");
            
$content $new_cache;
            
fwrite($fhandle,$content);
            
fclose($fhandle);
        
}
        
include $this->fragment_path $this->fragment_name;

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

Of course, you can either add ‘cache_fragment’ to the autoload, or do:

$this->load->library('cache_fragment'); 


Note: 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.

Note2: Nested fragment caching is not supported, because I’m lazy, if anyone really, absolutely needs it, I’ll sit down and add the feature.

Note3: Contact me with anything, really