ECMALL源码阅读七:模板缓存

ECMALL采用了自己编写的模板解析对象template(eccore/view/template.php),来实现代码与表现的分离。它在 实现了模板解析的同时,也实现了模板缓存。模板缓存为动态页面实现了静态化。减轻了服务器的CPU压力,提高了页面输出速度。 那么,它是如何保存缓存,以什么形式保存,保存在哪里呢?它又是如何识别缓存,并且读取出来的? template对象把模板缓存也就是生成的静态页面保存在temp文件夹的PHP文件中,当需要时,template对象根据cache_id识别缓存,并且判断缓存有效期,并且读取出来。

模板缓存保存(template.php)

<?php
/*如果需要缓存*/
if ($cache_id)
{
	/*生成缓存名称*/
	if ($this->appoint_cache_id)
	{
		$cachename = $cache_id;
	}
	else
	{
		$cachename = basename($filename, strrchr($filename, '.')) 
		. '_' . $cache_id;
	}
	/*生成缓存信息:有效期、生成时间*/
	$data = serialize(array('template' => $this->template, 
	'expires' => $this->_nowtime + $this->cache_lifetime, 
	'maketime' => $this->_nowtime));
	/*out是生成的静态页面*/
	$out = str_replace("\r", '', $out);

	while (strpos($out, "\n\n") !== false)
	{
		$out = str_replace("\n\n", "\n", $out);
	}

	/*把缓存写入文件*/
	if (file_put_contents($this->cache_dir . '/' . $cachename . '.php', 
	'<?php exit;?>' . $data . $out, LOCK_EX) === false)
	{
		trigger_error('can\'t write:' . $this->cache_dir .
		'/' . $cachename . '.php');
	}
	$this->template = array();
}
?>

模板缓存读取(template.php)

<?php
/*是否从缓存里读取*/
if (($this->caching == true || $this->appoint_cache_id) 
&& $this->direct_output == false)
{	
	/*缓存是否存在*/
	if (is_file($this->cache_dir . '/' . $cachename . '.php') && 
	($data = @file_get_contents($this->cache_dir . '/' . $cachename . '.php')))
	{
		$data = substr($data, 13);
		$pos  = strpos($data, '<');
		$paradata = substr($data, 0, $pos);
		$para     = @unserialize($paradata);
		/*是否在有效期内*/
		if ($para === false || $this->_nowtime > $para['expires'])
		{
			$this->caching = false;

			return false;
		}
		$this->_expires = $para['expires'];

		/*把缓存保存到template_out属性*/
		$this->template_out = substr($data, $pos);
	}
	else
	{
		$this->caching = false;

		return false;
	}

	return true;
}
?>