colly_wyx
2018-05-09 d3534714ed8f07f19e0a648ab2d07c73d0bed156
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
<?php
 
/**
 * Redis 拓展类
 * @author: 喵了个咪 <wenzhenxi@vip.qq.com> 2015-11-15
 *
 * @author: Axios <axioscros@aliyun.com> 2016-09-01
 *
 * @update 2016-09-01
 * 1. 增加__call魔术方法,重载当前类中方法,统一切换DB,缩减代码行数,减少类中方法互相调用时,重复切换DB
 * 2. 增加save_time方法,更新具有有效时间key的value,并且不重置有效时间,使用方式: DI()->redis->save_time($key, $value,$dbname);
 * 3. 增加counter_forever方法,永久计数器,每次调用递增1,使用方式: DI()->redis->counter_forever($key,$dbname);
 * 4. 增加counter_time_create方法,创建临时计数器,每次调用重置计数器和有效时间,使用方式: DI()->redis->counter_time_create($key,$expire,$dbname);
 * 5. 增加counter_time_update方法,更新临时计数器,每次调用递增1,使用方式: DI()->redis->counter_time_update($key,$dbname);
 * 6. 修复一处bug,get_time_ttl方法中,$this->unformatValue($value)修改为$value。修改前,调用此方法,会一直回调false
 *
 */
class Redis_Lite extends PhalApi_Cache_Redis{
 
    private $db_old;
 
    /**
     * 重载方法,统一切换DB
     *
     * @param $name
     * @param $arguments
     * @return mixed
     *
     * @author: Axios <axioscros@aliyun.com> 2016-09-01
     */
    public function __call($name, $arguments)
    {
        $last = count($arguments)-1;
        $dbname = $arguments[$last];
        $this->switchDB($dbname);
        unset($arguments[$last]);
        $arguments = empty($arguments)? array():$arguments;
        return call_user_func_array(array($this,$name),$arguments);
    }
 
    //---------------------------------------------------string类型-------------------------------------------------
    /**
     * 将value 的值赋值给key,生存时间为永久 并根据名称自动切换库
     */
    protected function set_forever($key, $value){
        return $this->redis->set($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 获取value 并根据名称自动切换库
     */
    protected function get_forever($key){
        $value = $this->redis->get($this->formatKey($key));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
 
    /**
     * 存入一个有实效性的键值队
     */
    protected function set_time($key, $value, $expire = 600){
        return $this->redis->setex($this->formatKey($key), $expire, $this->formatValue($value));
    }
 
 
    /**
     * 更新具有有效时间key的value,不重置有效时间
     * @author Axios <axioscros@aliyun.com>
     */
    protected function save_time($key, $value)
    {
        if($this->get_exists($key)){
            $ttl  = $this->get_time_ttl($key);
            return $this->set_time($key,$value,$ttl);
        }
 
        return NULL;
    }
 
    /**
     * 统一get/set方法,对于set_Time使用get_Time
     */
    protected function get_time($key){
        $value = $this->redis->get($this->formatKey($key));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
 
    /**
     * 得到一个key的生存时间
     */
    protected function get_time_ttl($key){
        $value = $this->redis->ttl($this->formatKey($key));
        return $value !== FALSE ? $value : NULL;
    }
 
    /**
     * 批量插入k-v,请求的v需要是一个数组 如下格式
     * array('key0' => 'value0', 'key1' => 'value1')
     */
    protected function set_list($value){
        $data = array();
        foreach($value as $k => $v){
            $data[$this->formatKey($k)] = $this->formatValue($v);
        }
        return $this->redis->mset($data);
    }
 
    /**
     * 批量获取k-v,请求的k需要是一个数组
     */
    protected function get_list($key){
        $data = array();
        foreach($key as $k => $v){
            $data[] = $this->formatKey($v);
        }
        $rs = $this->redis->mget($data);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
 
    /**
     * 判断key是否存在。存在 true 不在 false
     */
    protected function get_exists($key){
        return $this->redis->exists($this->formatKey($key));
    }
 
    /**
     * 返回原来key中的值,并将value写入key
     */
    protected function get_getSet($key, $value){
        $value = $this->redis->getSet($this->formatKey($key), $this->formatValue($value));
        return $value !== FALSE ? $this->unformatValue($value) : NULL;
    }
 
    /**
     * string,名称为key的string的值在后面加上value
     */
    protected function set_append($key, $value){
        return $this->redis->append($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 返回原来key中的值,并将value写入key
     */
    protected function get_strlen($key){
        return $this->redis->strlen($this->formatKey($key));
    }
 
    /**
     * 自动增长
     * value为自增长的值默认1
     */
    protected function get_incr($key, $value = 1){
        return $this->redis->incr($this->formatKey($key), $value);
    }
 
    /**
     * 自动减少
     * value为自减少的值默认1
     */
    protected function get_decr($key, $value = 1){
        return $this->redis->decr($this->formatKey($key), $value);
    }
    //------------------------------------------------List类型-------------------------------------------------
 
    /**
     * 写入队列左边 并根据名称自动切换库
     */
    protected function set_lPush($key, $value){
        return $this->redis->lPush($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 写入队列左边 如果value已经存在,则不添加 并根据名称自动切换库
     */
    protected function set_lPushx($key, $value){
        return $this->redis->lPushx($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 写入队列右边 并根据名称自动切换库
     */
    protected function set_rPush($key, $value){
        return $this->redis->rPush($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 写入队列右边 如果value已经存在,则不添加 并根据名称自动切换库
     */
    protected function set_rPushx($key, $value){
        return $this->redis->rPushx($this->formatKey($key), $this->formatValue($value));
    }
 
    /**
     * 读取队列左边
     */
    protected function get_lPop($key){
        $value = $this->redis->lPop($this->formatKey($key));
        return $value != FALSE ? $this->unformatValue($value) : NULL;
    }
 
    /**
     * 读取队列右边
     */
    protected function get_rPop($key){
        $value = $this->redis->rPop($this->formatKey($key));
        return $value != FALSE ? $this->unformatValue($value) : NULL;
    }
 
    /**
     * 读取队列左边 如果没有读取到阻塞一定时间 并根据名称自动切换库
     */
    protected function get_blPop($key){
        $value = $this->redis->blPop($this->formatKey($key), DI()->config->get('app.redis.blocking'));
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
 
    /**
     * 读取队列右边 如果没有读取到阻塞一定时间 并根据名称自动切换库
     */
    protected function get_brPop($key){
        $value = $this->redis->brPop($this->formatKey($key), DI()->config->get('app.redis.blocking'));
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
 
    /**
     * 名称为key的list有多少个元素
     */
    protected function get_lSize($key){
        return $this->redis->lSize($this->formatKey($key));
    }
 
    /**
     * 返回名称为key的list中指定位置的元素
     */
    protected function set_lSet($key, $index, $value){
        return $this->redis->lSet($this->formatKey($key), $index, $this->formatValue($value));
    }
 
    /**
     * 返回名称为key的list中指定位置的元素
     */
    protected function get_lGet($key, $index){
        $value = $this->redis->lGet($this->formatKey($key), $index);
        return $value != FALSE ? $this->unformatValue($value[1]) : NULL;
    }
 
    /**
     * 返回名称为key的list中start至end之间的元素(end为 -1 ,返回所有)
     */
    protected function get_lRange($key, $start, $end){
        $rs = $this->redis->lRange($this->formatKey($key), $start, $end);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
 
    /**
     * 截取名称为key的list,保留start至end之间的元素
     */
    protected function get_lTrim($key, $start, $end){
        $rs = $this->redis->lTrim($this->formatKey($key), $start, $end);
        foreach($rs as $k => $v){
            $rs[$k] = $this->unformatValue($v);
        }
        return $rs;
    }
 
    //未实现 lRem lInsert  rpoplpush
 
    //----------------------------------------------------set类型---------------------------------------------------
    //----------------------------------------------------zset类型---------------------------------------------------
    //----------------------------------------------------Hash类型---------------------------------------------------
 
    //----------------------------------------------------通用方法---------------------------------------------------
    /**
     * 永久计数器,回调当前计数
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_forever($key,$dbname=0){
        $this->switchDB($dbname);
        if($this->get_exists($key)){
            $count = $this->get_forever($key);
            $count++;
            $this->set_forever($key,$count);
        }else{
            $count = 1;
            $this->set_forever($key,$count);
        }
 
        return $count;
    }
    /**
     * 创建具有有效时间的计数器,回调当前计数,单位毫秒ms
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_time_create($key,$expire  = 1000,$dbname=0){
        $this->switchDB($dbname);
        $count = 1;
        $this->set_time($key,$count,$expire);
        $this->redis->pSetEx($this->formatKey($key), $expire, $this->formatValue($count));
        return $count;
    }
    /**
     * 更新具有有效时间的计数器,回调当前计数
     * @author Axios <axioscros@aliyun.com>
     */
    public function counter_time_update($key,$dbname=0){
        $this->switchDB($dbname);
        if($this->get_exists($key)){
            $count = $this->get_time($key);
            $count++;
            $expire = $this->redis->pttl($this->formatKey($key));
            $this->set_time($key,$count,$expire);
            return $count;
        }
        return false;
    }
    /**
     * 设定一个key的活动时间(s)
     */
    protected function setTimeout($key, $time = 600){
        return $this->redis->setTimeout($key, $time);
    }
 
    /**
     * 返回key的类型值
     */
    protected function type($key){
        return $this->redis->type($key);
    }
 
    /**
     * key存活到一个unix时间戳时间
     */
    protected function expireAt($key, $time = 600){
        return $this->redis->expireAt($key, $time);
    }
 
    /**
     * 随机返回key空间的一个key
     */
    public function randomKey(){
        return $this->redis->randomKey();
    }
 
    /**
     * 返回满足给定pattern的所有key
     */
    protected function keys($key, $pattern){
        return $this->redis->keys($key, $pattern);
    }
 
    /**
     * 查看现在数据库有多少key
     */
    protected function dbSize(){
        return $this->redis->dbSize();
    }
 
    /**
     * 转移一个key到另外一个数据库
     */
    protected function move($key, $db){
        $arr = DI()->config->get('app.redis.DB');
        $rs  = isset($arr[$db]) ? $arr[$db] : $db;
        return $this->redis->move($key, $rs);
    }
 
    /**
     * 给key重命名
     */
    protected function rename($key, $key2){
 
        return $this->redis->rename($key, $key2);
    }
 
    /**
     * 给key重命名 如果重新命名的名字已经存在,不会替换成功
     */
    protected function renameNx($key, $key2){
        return $this->redis->renameNx($key, $key2);
    }
 
    /**
     * 删除键值 并根据名称自动切换库(对所有通用)
     */
    protected function del($key){
        return $this->redis->del($this->formatKey($key));
    }
 
    /**
     * 返回redis的版本信息等详情
     */
    public function info(){
        return $this->redis->info();
    }
 
    /**
     * 切换DB并且获得操作实例
     */
    public function get_redis(){
        return $this->redis;
    }
 
    /**
     * 查看连接状态
     */
    public function ping(){
        return $this->redis->ping();
    }
 
    /**
     * 内部切换Redis-DB 如果已经在某个DB上则不再切换
     */
    protected function switchDB($name){
        $arr = DI()->config->get('app.redis.DB');
        if(is_int($name)){
            $db = $name;
        }else{
            $db = isset($arr[$name]) ? $arr[$name] : 0;
        }
        if($this->db_old != $db){
            $this->redis->select($db);
            $this->db_old = $db;
        }
    }
    //-------------------------------------------------------谨慎使用------------------------------------------------
 
    /**
     * 清空当前数据库
     */
    protected function flushDB(){
        return $this->redis->flushDB();
    }
 
    /**
     * 清空所有数据库
     */
    public function flushAll(){
        return $this->redis->flushAll();
    }
 
    /**
     * 选择从服务器
     */
    public function slaveof($host, $port){
        return $this->redis->slaveof($host, $port);
    }
 
    /**
     * 将数据同步保存到磁盘
     */
    public function save(){
        return $this->redis->save();
    }
 
    /**
     * 将数据异步保存到磁盘
     */
    public function bgsave(){
        return $this->redis->bgsave();
    }
 
    /**
     * 返回上次成功将数据保存到磁盘的Unix时戳
     */
    public function lastSave(){
        return $this->redis->lastSave();
    }
 
    /**
     * 使用aof来进行数据库持久化
     */
    protected function bgrewriteaof(){
        return $this->redis->bgrewriteaof();
    }
}