CodeIgniter Caching Problem with HTTP Headers (Content-Type)
Problem Description
I use
$this->output->cache(n);
to cache the file for at least n minutes. This works perfect for the first request the users’ browser makes. The second time, the files seem to have the Content-type text/html, so no custom header type is applied at all!How can I use caching and make sure the Content-Type header is also cached, so codeigniter does not fall back to text/html
Solution:
When you set a header via $this->output->set_header(), but also use caching via $this->output->cache(), those headers you sent will not be cached along with your content.
This can be very problematic: if you're caching CSS, for example, you want the cache to return that CSS along with the Content-Type header "text/css" - otherwise most browsers will interpret your CSS as just plain text, and hence not use it for rendering. With this simple extension to the Output class, headers will also be cached and returned.
Advantages over built-in cache
This extension is more memory efficient as the current (1.7.0) caching system, so even if you don't need the header caching, this extension is worth installing.
Instructions
Create a file in application/libraries named MY_Output.php ( as described in the user guide ) and copy/paste the following code:<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); /** * MY_Output * * Modified _write_cache and _display_cache to allow for header caching * works with CodeIgniter 1.7.0 * * @package CodeIgniter * @subpackage Libraries * @category Output * @author Arjen van Bochoven * @link http://codeigniter.com/wiki/Cache_headers */ class MY_Output extends CI_Output { // -------------------------------------------------------------------- /** * Write a Cache File * * @access public * @return void */ function _write_cache($output) { $CI =& get_instance(); $path = $CI->config->item('cache_path'); $cache_path = ($path == '') ? BASEPATH.'cache/' : $path; if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) { return; } $uri = $CI->config->item('base_url'). $CI->config->item('index_page'). $CI->uri->uri_string(); $cache_path .= md5($uri); if ( ! $fp = @fopen($cache_path, FOPEN_WRITE_CREATE_DESTRUCTIVE)) { log_message('error', "Unable to write cache file: ".$cache_path); return; } $expire = time() + ($this->cache_expiration * 60); if (flock($fp, LOCK_EX)) { fwrite($fp, serialize(array('exp' => $expire, 'headers' => $this->headers, 'output' => $output))); flock($fp, LOCK_UN); } else { log_message('error', "Unable to secure a file lock for file at: ".$cache_path); return; } fclose($fp); @chmod($cache_path, DIR_WRITE_MODE); log_message('debug', "Cache file written: ".$cache_path); } // -------------------------------------------------------------------- /** * Update/serve a cached file * * @access public * @return void */ function _display_cache(&$CFG, &$URI) { $cache_path = ($CFG->item('cache_path') == '') ? BASEPATH.'cache/' : $CFG->item('cache_path'); if ( ! is_dir($cache_path) OR ! is_really_writable($cache_path)) { return FALSE; } // 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; $filepath = $cache_path.md5($uri); if ( ! @file_exists($filepath)) { return FALSE; } if ( ! $fp = @fopen($filepath, FOPEN_READ)) { return FALSE; } flock($fp, LOCK_SH); $cache = ''; if (filesize($filepath) > 0) { $cache = fread($fp, filesize($filepath)); } flock($fp, LOCK_UN); fclose($fp); // Restore the cache array $cache = unserialize($cache); // Validate cache file if ( ! isset($cache['exp'] ) OR ! isset($cache['headers']) OR ! isset($cache['output'])) { return FALSE; } // Has the file expired? If so we'll delete it. if (time() >= trim($cache['exp'])) { @unlink($filepath); log_message('debug', "Cache file has expired. File deleted"); return FALSE; } // Restore headers $this->headers = $cache['headers']; // Display the cache $this->_display($cache['output']); log_message('debug', "Cache file is current. Sending it to browser."); return TRUE; } } Ref: https://github.com/EllisLab/CodeIgniter/wiki/Cache-headers
You can Eliminate cache by Passing Current Time stamp also.
ReplyDelete