文档章节

CI缓存机制

红科
 红科
发布于 2013/11/22 15:12
字数 1011
阅读 156
收藏 4

今天看下CI的文件缓存机制,使用起来的确很简单啊。把原理记下来:

1. 先说下使用方式吧:【这个是直接从手册,复制过来的】


启用缓存功能,只需要将下面的代码放入你的任何一个控制器(controller)的方法(function)内:

$this->output->cache(n);

其中n是你希望缓存更新的 分钟 数。可以使用 m/60 来精确到秒,例如 1/60 ,则是精确到 1秒

上面的代码可以放到任何一个 function 里面。他的出现顺序对缓存并没有影响,所以将它放在你认为最合乎逻辑的地方。一旦上面的代码放到了控制器的方法中,页面就会被缓存。

警告: 由于CI存储缓存文件的方式,只有通过 view 文件的输出才能被缓存。

注意: 在缓存文件产生之前,请确保application/cache文件夹可写。

2. 缓存运行原理

在CI的核心文件 CodeIgniter.php文件182行

/*
 * ------------------------------------------------------
 *	Is there a valid cache file? If so, we're done...
 * ------------------------------------------------------
 */
	if ($EXT->call_hook('cache_override') === FALSE
		&& $OUT->_display_cache($CFG, $URI) === TRUE)
	{
		exit;

	}

$EXT->call_hook('cache_override')  调用钩子,不存在返回false

$OUT->_display_cache($CFG, $URI) 判断缓存文件当前url下缓存文件是否存在

下面看看output类中 _display_cache方法

/**
	 * 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)
	{
		$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;
		$filepath = $cache_path.md5($uri);//带路径的缓存文件名

		if ( ! @file_exists($filepath) OR ! $fp = @fopen($filepath, FOPEN_READ))
		{
			return FALSE;
		}

		flock($fp, LOCK_SH);

		$cache = (filesize($filepath) > 0) ? fread($fp, filesize($filepath)) : '';

		flock($fp, LOCK_UN);
		fclose($fp);

		// 检查序列化文件信息
		if ( ! preg_match('/^(.*)ENDCI--->/', $cache, $match))
		{
			return FALSE;
		}

		$cache_info = unserialize($match[1]);
		$expire = $cache_info['expire'];//缓存的到期时间

		$last_modified = filemtime($cache_path);//取得文件的修改时间

		// 判断文件是否过期
		if ($_SERVER['REQUEST_TIME'] >= $expire && is_really_writable($cache_path))
		{
			// 如果已到期就删除
			@unlink($filepath);
			log_message('debug', 'Cache file has expired. File deleted.');
			return FALSE;
		}
		else
		{
			// Or else 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]);
		}

		//输出缓存
		$this->_display(substr($cache, strlen($match[0])));
		log_message('debug', 'Cache file is current. Sending it to browser.');
		return TRUE;
	}

再看看生成文件缓存的方法

/**
	 * Write Cache
	 *
	 * @param	string	$output	Output data to cache
	 * @return	void
	 */
	public function _write_cache($output)
	{
		$CI =& get_instance();
		$path = $CI->config->item('cache_path');
		$cache_path = ($path === '') ? APPPATH.'cache/' : $path;

		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();

		$cache_path .= md5($uri);//缓存的文件名就是MD5的当前url值

		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);//缓存时间

		// Put together our serialized info.
		$cache_info = serialize(array(
			'expire'	=> $expire,
			'headers'	=> $this->headers
		));

		if (flock($fp, LOCK_EX))
		{
			fwrite($fp, $cache_info.'ENDCI--->'.$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, FILE_WRITE_MODE);

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

还有缓存删除_delete_cache这里就不在粘贴了,详细看output类吧。

ci文件缓存是很明了,就是在载入视图后,生成一个md5的文件,然后 文件内容中有缓存到期时间,下此重新载入的时候,就可直接调用了

有一个缺点就是所有的缓存文件都放在同一个目录下,如果站点较大的话,自己可以修改,分级目录保存。

下面是CI论坛里一位牛人  优化缓存机制  扩展了 output类

http://codeigniter.org.cn/forums/forum.php?mod=viewthread&tid=11515

//=================================================================

今天用来CI文件缓存发现分页的时候不起作用,于是就看缓存的生成方式

$uri =	$CI->config->item('base_url').
				$CI->config->item('index_page').
				$CI->uri->uri_string();

$CI-uri-uri_string()这个方法不返回带有查询查询字符串的, 所以致使分页的缓存都是同一个文件名。的分页url后面是 ?page=&name=&是这种形式的  我把上述中的url改了一下

$uri =	$CI->config->item('base_url').
				$CI->config->item('index_page').
				$CI->input->server('REQUEST_URI');

搞定。

© 著作权归作者所有

共有 人打赏支持
红科
粉丝 9
博文 10
码字总数 2551
作品 0
济南
程序员
加载中

评论(3)

区域块链
区域块链
学习了
红科
红科

引用来自“walkskyer”的评论

0必须顶!!!

共同进步
walkskyer
walkskyer
0必须顶!!!
Drone 一个原生支持 docker 的 CI

大概是一年前发现了这样一个叫做 Drone 的开源 ci,在逐渐的尝试过程中发现它的功能非常的强大,其 pipeline as code + docker + backing service 支持的体系基本和我理想中的 ci 一模一样....

eisenxu
2017/11/03
0
0
POSCMS V3.2.18 发布,跨平台网站内容管理系统

POSCMS V3.2.18 已发布,PHP开源内容管理系统(PhpOpenSourceCMS简称POSCMS)是Php+Mysql开发的一款开源的跨平台网站内容管理系统。POSCMS系统基于CodeIgniter框架,具有良好扩展性和管理性。...

天睿云计算
04/24
0
0
CodeIgniter 框架分析

入口文件 入口文件主要完成下列工作: 1) 指定 CodeIgniter 框架所在目录; 2) 定义 APPPATH 常量,指示应用程序文件根目录; 3) 载入 codeigniter/CodeIgniter.php 文件,启动框架。 codeig...

那些年我们一起
2012/08/10
0
17
CodeIgniter框架文件结构

这个本来是很基础的东西,基本上用过CI的人都知道这些,原本是不消说的~但是因为毕业论文是关于CodeIgniter的,所以我必须把大大小小的东西都写出来做成记录~ CodeInigter,一个轻量,功能全面...

Scholer
2012/12/30
0
0
php缓冲 output_buffering的使用详解

本篇文章是对php缓冲output_buffering进行了详细的分析介绍,需要的朋友参考下 buffer buffer是一个内存地址空间,Linux系统默认大小一般为4096(4kb),即一个内存页。主要用于存储速度不同步的...

freedonn
2014/08/24
0
0

没有更多内容

加载失败,请刷新页面

加载更多

使用rancher界面化管理docker并部署springCloud项目的其中一个服务

一、先来个简单的 1.安装docker 2.安装eureka——运行docker命令安装 3.安装eureka——运行dokcer镜像安装 (1)构建eureka的镜像,网易云的docker镜像比较全一些,也可以去https://hub.docke...

monroeCode
23分钟前
3
0
理论与实践:如何从Hadoop迁移到MaxCompute

摘要:MaxCompute大数据计算服务,能提供快速、完全托管的PB级数据仓库解决方案,能够使用户经济且高效地分析处理海量数据。而用户往往之前使用了Hadoop实现大数据计算任务,在选择了阿里云大...

阿里云云栖社区
23分钟前
2
0
mysql: utf8 && utf8mb4

https://mathiasbynens.be/notes/mysql-utf8mb4 临时收藏

阿dai
35分钟前
2
0
面试宝典系列-nginx限流

Nginx自身有的请求限制模块ngx_http_limit_req_module、流量限制模块ngx_stream_limit_conn_module基于令牌桶算法,可以方便的控制令牌速率,自定义调节限流,实现基本的限流控制。 如何Ngi...

suyain
36分钟前
3
0
下拉框选择数据过滤?

需求:下拉框数据新增一条数据,已选择的不能再重新被选择 数据:存放表格数据的数组 scoreTable 下拉框数据 catorgaryArr 定义一个已经选择了的id数组 catorgaryIds 实现: arr 使用来保存每...

西园里的猫
40分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部