📄 正在查看:twcms/kongphp/cache/cache_memcache.class.php
1<?php
2/**
3 * Copyright (C) 2013-2014 www.kongphp.com All rights reserved.
4 * Licensed http://www.gnu.org/licenses/lgpl.html
5 * Author: wuzhaohuan <kongphp@gmail.com>
6 */
7
8defined('KONG_PATH') || exit;
9class cache_memcache implements cache_interface{
10 private $conf;
11 private $is_getmulti = FALSE; //是否支持 getMulti 方法
12 public $pre; //缓存前缀 (防止同一台缓存服务器,有多套程序,键名冲突问题)
13
14 public function __construct(&$conf) {
15 $this->conf = &$conf;
16 $this->pre = $conf['pre'];
17 }
18
19 public function __get($var) {
20 $c = $this->conf['memcache'];
21 if($var == 'memcache') {
22 // 判断 Mongo 扩展是否安装
23 if(extension_loaded('Memcached')) {
24 $this->memcache = new Memcached;
25 }elseif(extension_loaded('Memcache')) {
26 $this->memcache = new Memcache;
27 }else{
28 throw new Exception('Memcache Extension not loaded.');
29 }
30
31 if(!$this->memcache) {
32 throw new Exception('PHP.ini Error: Memcache extension not loaded.');
33 }
34
35 if($this->memcache->connect($c['host'], $c['port'])) {
36 if(!empty($c['multi'])) {
37 $this->is_getmulti = method_exists($this->memcache, 'getMulti');
38 }
39 return $this->memcache;
40 }else{
41 throw new Exception('Can not connect to Memcached host.');
42 }
43 }
44 }
45
46 /**
47 * 读取一条数据
48 * @param string $key 键名
49 * @return array
50 */
51 public function get($key) {
52 return $this->memcache->get($this->pre.$key);
53 }
54
55 /**
56 * 读取多条数据
57 * @param array $keys 键名数组
58 * @return array
59 */
60 public function multi_get($keys) {
61 $data = array();
62 // 支持 getMulti 方法
63 if($this->is_getmulti) {
64 // 补上缓存前缀
65 $m_keys = array();
66 foreach ($keys as $i=>$k) {
67 $m_keys[$i] = $this->pre.$k;
68 }
69 $m_data = $this->memcache->getMulti($m_keys);
70 foreach($keys as $k) {
71 if(empty($m_data[$this->pre.$k])) {
72 $data[$k] = FALSE;
73 }else{
74 $data[$k] = $m_data[$this->pre.$k];
75 }
76 }
77 }else{
78 foreach($keys as $k) {
79 $arr = $this->memcache->get($this->pre.$k);
80 if(empty($arr)) {
81 $data[$k] = FALSE;
82 }else{
83 $data[$k] = $arr;
84 }
85 }
86 }
87 return $data;
88 }
89
90 /**
91 * 写入一条数据
92 * @param string $key 键名
93 * @param array $data 数据
94 * @param int $life 缓存时间 (默认为永久)
95 * @return bool
96 */
97 public function set($key, $data, $life = 0) {
98 // 二级缓存开启时,写入最新微秒时间
99 if($this->conf['l2_cache'] === 1) {
100 $this->memcache->delete($this->pre.'_l2_cache_time');
101 }
102 return $this->memcache->set($this->pre.$key, $data, 0, $life);
103 }
104
105 /**
106 * 更新一条数据
107 * @param string $key 键名
108 * @param array $data 数据
109 * @param int $life 缓存时间 (默认为永久)
110 * @return bool
111 */
112 public function update($key, $data, $life = 0) {
113 $key = $this->pre.$key;
114 $arr = $this->get($key);
115 if($arr !== FALSE) {
116 is_array($arr) && is_array($data) && $arr = array_merge($arr, $data);
117 return $this->set($key, $arr, $life);
118 }
119 return FALSE;
120 }
121
122 /**
123 * 删除一条数据
124 * @param string $key 键名
125 * @return bool
126 */
127 public function delete($key) {
128 // 二级缓存开启时,写入最新微秒时间
129 if($this->conf['l2_cache'] === 1) {
130 $this->memcache->delete($this->pre.'_l2_cache_time');
131 }
132 return $this->memcache->delete($this->pre.$key);
133 }
134
135 /**
136 * 获取/设置最大ID
137 * @param string $table 表名
138 * @param boot/int $val 值 (为 FALSE 时为获取)
139 * @return int
140 */
141 public function maxid($table, $val = FALSE) {
142 $key = $table.'-Auto_increment';
143 if($val === FALSE) {
144 return intval($this->get($key));
145 }else{
146 $this->set($key, $val);
147 return $val;
148 }
149 }
150
151 /**
152 * 获取/设置总条数
153 * @param string $table 表名
154 * @param boot/int $val 值 (为 FALSE 时为获取)
155 * @return int
156 */
157 public function count($table, $val = FALSE) {
158 $key = $table.'-Rows';
159 if($val === FALSE) {
160 return intval($this->get($key));
161 }else{
162 $this->set($key, $val);
163 return $val;
164 }
165 }
166
167 /**
168 * 清空缓存
169 * @param string $pre 前缀
170 * @return boot
171 */
172 public function truncate($pre = '') {
173 return $this->memcache->flush();
174 }
175
176 /**
177 * 读取一条二级缓存
178 * @param string $l2_key 二级缓存键名
179 * @return boot
180 */
181 public function l2_cache_get($l2_key) {
182 $l2_cache_time = $this->get('_l2_cache_time'); // 最后更新数据微秒时间,用来控制缓存
183 $l2_key_time = $this->get($l2_key.'_time'); // 用来和 $l2_cache_time 对比是否一样
184 if($l2_cache_time && $l2_cache_time === $l2_key_time) {
185 return $this->get($l2_key); // 从缓存中读取数据
186 }
187 return FALSE;
188 }
189
190 /**
191 * 写入一条二级缓存
192 * @param string $l2_key 二级缓存键名
193 * @param string $keys 键名数组
194 * @return boot
195 */
196 public function l2_cache_set($l2_key, $keys, $life = 0) {
197 $l2_cache_time = $this->get('_l2_cache_time'); // 最后更新数据微秒时间,用来控制缓存
198 if(empty($l2_cache_time)) {
199 $l2_cache_time = microtime(1);
200 $this->memcache->set($this->pre.'_l2_cache_time', $l2_cache_time, 0, 0);
201 }
202 $this->memcache->set($this->pre.$l2_key.'_time', $l2_cache_time, 0, $life); // 把最后更新数据微秒时间写入缓存
203 return $this->memcache->set($this->pre.$l2_key, $keys, 0, $life); // 把数据写入缓存
204 }
205}
206?>
207