discuz缓存机制
一、 discuz缓存机制分析:
使用缓存机制的目的很明显,降低服务器性能的消耗,对于常用且变动比较小的数据的数据,可以尽可能的使用缓存来解决,代替最原生的不断的进行数据库查询匹配的过程。而Discuz中提供的数据缓存方式包括内存、数据库、文件三种方式,具体如下。
(1)、项目根目录/config/config_global.php配置数据库/文件缓存方式,当然还有第三种,就是内存缓存。
$_config['cache']['type'] = 'sql';//file
(2)、缓存数据获取:
根目录/source/function/function_core.php:
function loadcache($cachenames, $force = false) {
global $_G;
static $loadedcache = array();
$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
$caches = array();
foreach ($cachenames as $k) {
if(!isset($loadedcache[$k]) || $force) {
$caches[] = $k;
$loadedcache[$k] = true;
}
}
if(!empty($caches)) {
$cachedata = C::t('common_syscache')->fetch_all($caches);
foreach($cachedata as $cname => $data) {
if($cname == 'setting') {
$_G['setting'] = $data;
} elseif($cname == 'usergroup_'.$_G['groupid']) {
$_G['cache'][$cname] = $_G['group'] = $data;
} elseif($cname == 'style_default') {
$_G['cache'][$cname] = $_G['style'] = $data;
} elseif($cname == 'grouplevels') {
$_G['grouplevels'] = $data;
} else {
$_G['cache'][$cname] = $data;
}
}
}
return true;
}
从函数中可以看出,数据缓存其实相当于把一些常用的数据,通过特定的需求,根据缓存的方式存储于文件 或者 表(前缀)_common_syscache 或者 内存中,当需要使用到某个类型的数据的时候,只需要在代码中加入类似loadcache('setting');,就可以获取到缓存数据并赋值于自定义全局变量$_G中,即$_G['setting']; ,其中fetch_all中会判断当前使用的是哪一种缓存方式,如下该函数:
脚本:table_common_syscache.php
public function fetch_all($cachenames) {
$data = array();
$cachenames = is_array($cachenames) ? $cachenames : array($cachenames);
if($this->_allowmem) {
$data = memory('get', $cachenames);
$newarray = $data !== false ? array_diff($cachenames, array_keys($data)) : $cachenames;
if(empty($newarray)) {
return $data;
} else {
$cachenames = $newarray;
}
}
if($this->_isfilecache) {
$lostcaches = array();
foreach($cachenames as $cachename) {
if(!@include_once(DISCUZ_ROOT.'./data/cache/cache_'.$cachename.'.php')) {
$lostcaches[] = $cachename;
} elseif($this->_allowmem) {
memory('set', $cachename, $data[$cachename]);
}
}
if(!$lostcaches) {
return $data;
}
$cachenames = $lostcaches;
unset($lostcaches);
}
$query = DB::query('SELECT * FROM '.DB::table($this->_table).' WHERE '.DB::field('cname', $cachenames));
while($syscache = DB::fetch($query)) {
$data[$syscache['cname']] = $syscache['ctype'] ? unserialize($syscache['data']) : $syscache['data'];
$this->_allowmem && (memory('set', $syscache['cname'], $data[$syscache['cname']]));
if($this->_isfilecache) {
$cachedata = '$data[\''.$syscache['cname'].'\'] = '.var_export($data[$syscache['cname']], true).";\n\n";
if(($fp = @fopen(DISCUZ_ROOT.'./data/cache/cache_'.$syscache['cname'].'.php', 'wb'))) {
fwrite($fp, "<?php\n//Discuz! cache file, DO NOT modify me!\n//Identify: ".md5($syscache['cname'].$cachedata.getglobal('config/security/authkey'))."\n\n$cachedata?>");
fclose($fp);
}
}
}
foreach($cachenames as $name) {
if($data[