CodeIgniter - how to selectively cache output? CodeIgniter - how to selectively cache output? codeigniter codeigniter

CodeIgniter - how to selectively cache output?


I'm sure someone will correct me if I'm wrong but I believe codeigniter caching only allows the caching of full pages. There are some additional libraries which enable partial page caching, check out phil sturgeons effort here:http://getsparks.org/packages/cache/show

My personal approach is to not bother with page caching and just use database caching which is more selective - but if you want/need page caching then I think the above is the only way to go


Codeigniter do not separate cache by visitor and authenticated user.

Otherwise you can do it by yourself by override output class.Create MY_Output.php in CI/application/core

This is my code for latest project.

class MY_Output extends CI_Output

{

/** * Write Cache * * @param   string  $output Output data to cache * @return  void */public function _write_cache($output){    $CI =& get_instance();    //-XXX CUSTOM------------------------------------    $cache_path = $this->cachePath();    //-----------------------------------------------    if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path))    {        log_message('error', 'Unable to write cache file: '.$cache_path);        return;    }    $uri = $CI->config->item('base_url')        .$CI->config->item('index_page')        .$CI->uri->uri_string();    if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))    {        if (is_array($cache_query_string))        {            $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));        }        else        {            $uri .= '?'.$_SERVER['QUERY_STRING'];        }    }    $cache_path .= md5($uri);    if ( ! $fp = @fopen($cache_path, 'w+b'))    {        log_message('error', 'Unable to write cache file: '.$cache_path);        return;    }    if ( ! flock($fp, LOCK_EX))    {        log_message('error', 'Unable to secure a file lock for file at: '.$cache_path);        fclose($fp);        return;    }    // If output compression is enabled, compress the cache    // itself, so that we don't have to do that each time    // we're serving it    if ($this->_compress_output === TRUE)    {        $output = gzencode($output);        if ($this->get_header('content-type') === NULL)        {            $this->set_content_type($this->mime_type);        }    }    $expire = time() + ($this->cache_expiration * 60);    // Put together our serialized info.    $cache_info = serialize(array(        'expire'    => $expire,        'headers'   => $this->headers    ));    $output = $cache_info.'ENDCI--->'.$output;    for ($written = 0, $length = self::strlen($output); $written < $length; $written += $result)    {        if (($result = fwrite($fp, self::substr($output, $written))) === FALSE)        {            break;        }    }    flock($fp, LOCK_UN);    fclose($fp);    if ( ! is_int($result))    {        @unlink($cache_path);        log_message('error', 'Unable to write the complete cache content at: '.$cache_path);        return;    }    chmod($cache_path, 0640);    log_message('debug', 'Cache file written: '.$cache_path);    // Send HTTP cache-control headers to browser to match file cache settings.    $this->set_cache_header($_SERVER['REQUEST_TIME'], $expire);}// --------------------------------------------------------------------/** * Update/serve cached output * * @uses    CI_Config * @uses    CI_URI * * @param   object  &$CFG   CI_Config class instance * @param   object  &$URI   CI_URI class instance * @return  bool    TRUE on success or FALSE on failure */public function _display_cache(&$CFG, &$URI){    //-XXX CUSTOM------------------------------------    $cache_path = $this->cachePath($CFG);    //$cache_path = ($CFG->item('cache_path') === '') ? APPPATH.'cache/' : $CFG->item('cache_path');    //-----------------------------------------------    // Build the file path. The file name is an MD5 hash of the full URI    $uri = $CFG->item('base_url').$CFG->item('index_page').$URI->uri_string;    if (($cache_query_string = $CFG->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))    {        if (is_array($cache_query_string))        {            $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));        }        else        {            $uri .= '?'.$_SERVER['QUERY_STRING'];        }    }    $filepath = $cache_path.md5($uri);    if ( ! file_exists($filepath) OR ! $fp = @fopen($filepath, 'rb'))    {        return FALSE;    }    flock($fp, LOCK_SH);    $cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';    flock($fp, LOCK_UN);    fclose($fp);    // Look for embedded serialized file info.    if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match))    {        return FALSE;    }    $cache_info = unserialize($match[1]);    $expire = $cache_info['expire'];    $last_modified = filemtime($filepath);    // Has the file expired?    if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))    {        // If so we'll delete it.        @unlink($filepath);        log_message('debug', 'Cache file has expired. File deleted.');        return FALSE;    }    // Send the HTTP cache control headers    $this->set_cache_header($last_modified, $expire);    // Add headers from cache file.    foreach ($cache_info['headers'] as $header)    {        $this->set_header($header[0], $header[1]);    }    //-XXX CUSTOM------------------------------------    $exTime = $this->executionTime();    setcookie('exe_time', "$exTime", time()+120, '/');    //-----------------------------------------------    // Display the cache    $this->_display(self::substr($cache, self::strlen($match[0])));    log_message('debug', 'Cache file is current. Sending it to browser.');    return TRUE;}// --------------------------------------------------------------------/** * Delete cache * * @param   string  $uri    URI string * @return  bool */public function delete_cache($uri = ''){    $CI =& get_instance();    //-XXX CUSTOM------------------------------------    $cache_path = $CI->config->item('cache_path');    $cache_path = ($cache_path === '') ? APPPATH.'cache/' : $cache_path;    //-----------------------------------------------    if ( ! is_dir($cache_path))    {        log_message('error', 'Unable to find cache path: '.$cache_path);        return FALSE;    }    if (empty($uri))    {        $uri = $CI->uri->uri_string();        if (($cache_query_string = $CI->config->item('cache_query_string')) && ! empty($_SERVER['QUERY_STRING']))        {            if (is_array($cache_query_string))            {                $uri .= '?'.http_build_query(array_intersect_key($_GET, array_flip($cache_query_string)));            }            else            {                $uri .= '?'.$_SERVER['QUERY_STRING'];            }        }    }    //-XXX CUSTOM------------------------------------    $passed = TRUE;    $path1 = $cache_path.'xmember/'.md5($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/'));    if ( ! @unlink($path1))    {        log_message('error', 'Unable to delete cache file for '.$uri);        $passed = FALSE;    }    $path2 = $cache_path.'xvisitor/'.md5($CI->config->item('base_url').$CI->config->item('index_page').ltrim($uri, '/'));    if ( ! @unlink($path2))    {        log_message('error', 'Unable to delete cache file for '.$uri);        $passed = FALSE;    }    //-----------------------------------------------    return $passed;}private function cachePath(&$CFG=false){    $hasSession = !empty($_COOKIE[COOKIE_CUSTOMER_SESSION_ID]);    if(empty($CFG)) {        $CI =& get_instance();        $CFG = $CI->config;    }    $path = $CFG->item('cache_path');    $path = empty($path) ? APPPATH.'cache/' : $path;    $path .= $hasSession?'xmember/':'xvisitor/';    return $path;}function executionTime(){    $time = microtime();    $time = explode(' ', $time);    $time = $time[1] + $time[0];    $total_time = round(($time - LOAD_PAGE_START), 4); //second unit    return $total_time;}

}