ecshop缓存详解
小结:主要根据$cache_id,caching参数判断是否需要缓存,若缓存文件存在且未过期则直接从缓存文件中读取缓存,若缓存文件过期则重新编译,判断编译文件是否过期,若未过期则直接生成缓存,若过期了则重新编译。
- is_cached方法解析
- display页面呈现方法
- catch页面编译方法
代码块
判断缓存是否存在:
#判断是否存在该页面的缓存
if (!$smarty->is_cached('index.dwt', $cache_id))
{
#do something ...
}
$smarty->display('index.dwt', $cache_id);
---------------------------------------------------------
#判断缓存函数
function is_cached($filename, $cache_id = '')
{
$cachename = basename($filename, strrchr($filename, '.')) . '_' . $cache_id;
if ($this->caching == true && $this->direct_output == false)
{
$hash_dir = $this->cache_dir . '/' . substr(md5($cachename), 0, 1);
#判断缓存文件是否存在
if ($data = @file_get_contents($hash_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);
#判断每一个模板是否过期
foreach ($para['template'] AS $val)
{
$stat = @stat($val);
if ($para['maketime'] < $stat['mtime'])
{
$this->caching = false;
return false;
}
}
}
else
{
$this->caching = false;
return false;
}
return true;
}
else
{
return false;
}
}
---------------------------------------------------------
#根据上面的is_cached判断是否从缓存中读取
function display($filename, $cache_id = '')
{
$this->_seterror++;
error_reporting(E_ALL ^ E_NOTICE);
$this->_checkfile = false;
#此处处理文件的呈现
$out = $this->fetch($filename, $cache_id);
if (strpos($out, $this->_echash) !== false)
{
$k = explode($this->_echash, $out);
foreach ($k AS $key => $val)
{
if (($key % 2) == 1)
{
$k[$key] = $this->insert_mod($val);
}
}
$out = implode('', $k);
}
error_reporting($this->_errorlevel);
$this->_seterror--;
echo $out;
}
---------------------------------------------------------
/**
* 处理模板文件
*
* @access public
* @param string $filename
* @param sting $cache_id
*
* @return sring
*/
function fetch($filename, $cache_id = '')
{
if (!$this->_seterror)
{
error_reporting(E_ALL ^ E_NOTICE);
}
$this->_seterror++;
if (strncmp($filename,'str:', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}
else
{
if ($this->_checkfile)
{
if (!file_exists($filename))
{
$filename = $this->template_dir . '/' . $filename;
}
}
else
{
$filename = $this->template_dir . '/' . $filename;
}
if ($this->direct_output)
{
$this->_current_file = $filename;
#如果direct_output为真,就直接输出不用缓存
$out = $this->_eval($this->fetch_str(file_get_contents($filename)));
}
else
{
#有缓存id和caching为真,则直接读取缓存到$out中
if ($cache_id && $this->caching)
{
$out = $this->template_out;
}
else
{
if (!in_array($filename, $this->template))
{
$this->template[] = $filename;
}
#如果缓存文件不存在则编译源文件
$out = $this->make_compiled($filename);
if ($cache_id)
{
#如果存在cache_id存在则生成一份缓存保存
$cachename = basename($filename, strrchr($filename, '.')) . '_' . $cache_id;
$data = serialize(array('template' => $this->template, 'expires' => $this->_nowtime + $this->cache_lifetime, 'maketime' => $this->_nowtime));
$out = str_replace("\r", '', $out);
while (strpos($out, "\n\n") !== false)
{
$out = str_replace("\n\n", "\n", $out);
}
$hash_dir = $this->cache_dir . '/' . substr(md5($cachename), 0, 1);
if (!is_dir($hash_dir))
{
mkdir($hash_dir);
}
if (file_put_contents($hash_dir . '/' . $cachename . '.php', '<?php exit;?>' . $data . $out, LOCK_EX) === false)
{
trigger_error('can\'t write:' . $hash_dir . '/' . $cachename . '.php');
}
$this->template = array();
}
}
}
}
$this->_seterror--;
if (!$this->_seterror)
{
error_reporting($this->_errorlevel);
}
return $out; // 返回html数据
}
来源:CSDN
作者:徐乐乐1
链接:https://blog.csdn.net/b1303110335/article/details/51565325