-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Fragment Caching Library
Contibutors:Libraries::Caching
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
// [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($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