让Codeigniter缓存CSS和JS等类型的文件

Published at 7 months ago

虽然Codeigniter可以通过 $this->output->set_header(); 来设置文件类型,但当使用Cache功能来缓存非text/html类型的文件时,输出时依然是text/html 要让缓存文件也可以输出成css、js等非text/html类型文件,只需添加一个增强类库即可,方法如下:

  1. 在application/libraries文件夹下,新建一个文件名为MY_Output.php的文件(注意文件名的大小写)文件内容见下文
  2. 在使用缓存指令$this->output->cache();之前引用该类库:$this->load->library('MY_Output');$this->output->cache();

如此便可缓存并输出css和js类型的文件了。 MY_Output.php内容:

<?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;
}
}

#PHP

@http://zfben.com/blog/让Codeigniter缓存CSS和JS等类型的文件