关于discuzX的缓存代码有点不明白的地方,请教大家

发布于 2021-11-15 10:05:09 字数 3311 浏览 880 评论 5

 

class discuz_memory
{
	var $config;
	var $extension = array();
	var $memory;
	var $prefix;
	var $type;
	var $keys;
	var $enable = false;
    //构造函数,检查eaccelerator,xcach,memcache是否存在
	function discuz_memory() {
		$this->extension['eaccelerator'] = function_exists('eaccelerator_get');
		$this->extension['xcache'] = function_exists('xcache_get');
		$this->extension['memcache'] = extension_loaded('memcache');
	}

	function init($config) {
         //内存存储配置
		$this->config = $config;
		//键值前缀
		$this->prefix = empty($config['prefix']) ? substr(md5($_SERVER['HTTP_HOST']), 0, 6).'_' : $config['prefix'];
		$this->keys = array();
        //memcache存储
		if($this->extension['memcache'] && !empty($config['memcache']['server'])) {
			require_once libfile('class/memcache');
			$this->memory = new discuz_memcache();
			$this->memory->init($this->config['memcache']);
			if(!$this->memory->enable) {
				$this->memory = null;
			}
		}
        //如果memcache联接失败,用eaccelerator
		if(!is_object($this->memory) && $this->extension['eaccelerator'] && $this->config['eaccelerator']) {
			require_once libfile('class/eaccelerator');
			$this->memory = new discuz_eaccelerator();
			$this->memory->init(null);
		}
        //使用xcache
		if(!is_object($this->memory) && $this->extension['xcache'] && $this->config['xcache']) {
			require_once libfile('class/xcache');
			$this->memory = new discuz_xcache();
			$this->memory->init(null);
		}
        //确定缓存对象
		if(is_object($this->memory)) {
			$this->enable = true;
			//缓存类型
			$this->type = str_replace('discuz_', '', get_class($this->memory));
			$this->keys = $this->get('memory_system_keys');
			//是否存在memory_system_keys己经存在的key,没有则初始化
			$this->keys = !is_array($this->keys) ? array() : $this->keys;
		}

	}

	function get($key) {
		$ret = null;
		if($this->enable && (isset($this->keys[$key]) || $key == 'memory_system_keys')) {
			$ret = $this->memory->get($this->_key($key));
			if(!is_array($ret)) {
				$ret = null;
			} else {
				return $ret[0];
			}
		}
		return $ret;
	}

	function set($key, $value, $ttl = 0) {

		$ret = null;
		if($this->enable) {
			$ret = $this->memory->set($this->_key($key), array($value), $ttl);
			if($ret) {
				//这个地方不明白?为什么要把所有的Key存入到$this->keys中呢?还要存入到memory_system_keys,//这样不担心存入的key特别的多(如有一百万个缓存),每次请求的时候不担心占用大量的内存???
				$this->keys[$key] = true;
				$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
			}
		}
		return $ret;
	}

	function rm($key) {
		$ret = null;
		if($this->enable) {
			$ret = $this->memory->rm($this->_key($key));
			if($ret) {
				unset($this->keys[$key]);
				$this->memory->set($this->_key('memory_system_keys'), array($this->keys));
			}
		}
		return $ret;
	}

	function clear() {
		if($this->enable && is_array($this->keys)) {
			$this->keys['memory_system_keys'] = true;
			foreach ($this->keys as $k => $v) {
				$this->memory->rm($this->_key($k));
			}
		}
		$this->keys = array();
		return true;
	}

	function _key($str) {
		return ($this->prefix).$str;
	}

}

 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夜司空 2021-11-16 04:48:38

把$this->keys打印出来看看。。

妖妓 2021-11-16 04:39:27

引用来自#4楼“杨金焕”的帖子

首先要要明确两点知识:

1、PHP类的知识,它是实例化,全局使用,不做第二次实例(在discuz里),$this->keys[$key] = true;   在全局里就可以判断某个key已经缓存,如果在某个地方做了缓存,再到其它位置(php同一个进行时的不同位置)要做同样的事情,就可以知道某个$this->keys[$key] 已存在(当然会检查是否有效,过期),不需要再调用缓存set(),而直接可以返回缓存。

2、php缓存的原理,无非就是第一次检查是否存在key的缓存,如果没有就设置key=>value,其它不同的请求,就检查同用的key(在有效期内)是否存在,就调用,不用再做获存数据这个复杂耗时的过程,起到加速的作用。(当然缓存中间件会有如下的设定:过期,总缓存的总容量这些重要的设定参数,如超过容量合子,新设定的缓存会把旧的缓存挤出缓存合子)。

实现代码一般是这样:

$cache_obj  = 'some cahce object';

if(!$data = $cache_obj->get(‘news_threads’)){

//做了好复杂的数据查询,处理,过滤,整理等工作,非常耗时的过程,得到data这个大型的数据

$data = $value //may be array(');

$cache_obj->set('news_threads', $data);

}

//以下是对$data这个数据进行使用,输出

var_dump($data)

.......

//又有一个地方,在同一个php文件里,可能要用到news_threads这个缓存key,

可以直接这样判断$cache_obj->isset(''news_threads);

带上头具痛哭 2021-11-16 03:53:17

首先要要明确两点知识:

1、PHP类的知识,它是实例化,全局使用,不做第二次实例(在discuz里),$this->keys[$key] = true;   在全局里就可以判断某个key已经缓存,如果在某个地方做了缓存,再到其它位置(php同一个进行时的不同位置)要做同样的事情,就可以知道某个$this->keys[$key] 已存在(当然会检查是否有效,过期),不需要再调用缓存set(),而直接可以返回缓存。

2、php缓存的原理,无非就是第一次检查是否存在key的缓存,如果没有就设置key=>value,其它不同的请求,就检查同用的key(在有效期内)是否存在,就调用,不用再做获存数据这个复杂耗时的过程,起到加速的作用。(当然缓存中间件会有如下的设定:过期,总缓存的总容量这些重要的设定参数,如超过容量合子,新设定的缓存会把旧的缓存挤出缓存合子)。

实现代码一般是这样:

$cache_obj  = 'some cahce object';

if(!$data = $cache_obj->get(‘news_threads’)){

//做了好复杂的数据查询,处理,过滤,整理等工作,非常耗时的过程,得到data这个大型的数据

$data = $value //may be array(');

$cache_obj->set('news_threads', $data);

}

//以下是对$data这个数据进行使用,输出

var_dump($data)

.......

//又有一个地方,在同一个php文件里,可能要用到news_threads这个缓存key,

可以直接这样判断$cache_obj->isset(''news_threads);

风苍溪 2021-11-16 03:15:43

理论上, Key=>Value 这种方式的缓存寻址时间是一样的.

吃颗糖壮壮胆 2021-11-15 23:00:33
  1.  if($ret) {  
  2.                 //这个地方不明白?为什么要把所有的Key存入到$this->keys中呢?还要存入到memory_system_keys,//这样不担心存入的key特别的多(如有一百万个缓存),每次请求的时候不担心占用大量的内存???  
  3.                 $this->keys[$key] = true;  
  4.                 $this->memory->set($this->_key('memory_system_keys'), array($this->keys));  
  5.             }  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文