林一峰
7 years ago
13 changed files with 1481 additions and 45 deletions
-
973app/Common/Redis.php
-
398app/Common/RedisCluster.php
-
2app/Common/Token.php
-
26app/Http/Controllers/Home/IndexController.php
-
25config/custom.php
-
53lqycms.sql
-
1public/css/style.css
-
BINpublic/images/logo.png
-
2resources/views/home/common/footer.blade.php
-
18resources/views/home/common/header.blade.php
-
2resources/views/weixin/collect_goods/index.blade.php
-
12resources/views/weixin/goods/categoryGoodsList.blade.php
-
14resources/views/weixin/user/index.blade.php
@ -0,0 +1,973 @@ |
|||
<?php |
|||
namespace App\Common; |
|||
|
|||
/** |
|||
* redis操作类 |
|||
* 说明,任何为false的串,存在redis中都是空串。 |
|||
* 只有在key不存在时,才会返回false。 |
|||
* 这点可用于防止缓存穿透 |
|||
* |
|||
*/ |
|||
class Redis |
|||
{ |
|||
private $redis; |
|||
|
|||
//当前数据库ID号
|
|||
protected $dbId=0; |
|||
|
|||
//当前权限认证码
|
|||
protected $auth; |
|||
|
|||
/** |
|||
* 实例化的对象,单例模式. |
|||
* @var \iphp\db\Redis |
|||
*/ |
|||
static private $_instance=array(); |
|||
|
|||
private $k; |
|||
|
|||
//连接属性数组
|
|||
protected $attr=array( |
|||
//连接超时时间,redis配置文件中默认为300秒
|
|||
'timeout'=>30, |
|||
//选择的数据库。
|
|||
'db_id'=>0, |
|||
); |
|||
|
|||
//什么时候重新建立连接
|
|||
protected $expireTime; |
|||
|
|||
protected $host; |
|||
protected $port; |
|||
|
|||
private function __construct($config,$attr=array()) |
|||
{ |
|||
$this->attr = array_merge($this->attr,$attr); |
|||
$this->redis = new \Redis(); |
|||
$this->port = $config['port'] ? $config['port'] : 6379; |
|||
$this->host = $config['host']; |
|||
$this->redis->connect($this->host, $this->port, $this->attr['timeout']); |
|||
|
|||
if($config['auth']) |
|||
{ |
|||
$this->auth($config['auth']); |
|||
$this->auth = $config['auth']; |
|||
} |
|||
|
|||
$this->expireTime = time() + $this->attr['timeout']; |
|||
} |
|||
|
|||
/** |
|||
* 得到实例化的对象. |
|||
* 为每个数据库建立一个连接 |
|||
* 如果连接超时,将会重新建立一个连接 |
|||
* @param array $config |
|||
* @param int $dbId |
|||
* @return \iphp\db\Redis |
|||
*/ |
|||
public static function getInstance($config, $attr = array()) |
|||
{ |
|||
//如果是一个字符串,将其认为是数据库的ID号。以简化写法。
|
|||
if(!is_array($attr)) |
|||
{ |
|||
$dbId = $attr; |
|||
$attr = array(); |
|||
$attr['db_id'] = $dbId; |
|||
} |
|||
|
|||
$attr['db_id'] = $attr['db_id'] ? $attr['db_id'] : 0; |
|||
|
|||
|
|||
$k = md5(implode('', $config).$attr['db_id']); |
|||
if(! (static::$_instance[$k] instanceof self)) |
|||
{ |
|||
static::$_instance[$k] = new self($config,$attr); |
|||
static::$_instance[$k]->k = $k; |
|||
static::$_instance[$k]->dbId = $attr['db_id']; |
|||
|
|||
//如果不是0号库,选择一下数据库。
|
|||
if($attr['db_id'] != 0){ |
|||
static::$_instance[$k]->select($attr['db_id']); |
|||
} |
|||
} |
|||
elseif( time() > static::$_instance[$k]->expireTime) |
|||
{ |
|||
static::$_instance[$k]->close(); |
|||
static::$_instance[$k] = new self($config,$attr); |
|||
static::$_instance[$k]->k = $k; |
|||
static::$_instance[$k]->dbId = $attr['db_id']; |
|||
|
|||
//如果不是0号库,选择一下数据库。
|
|||
if($attr['db_id']!=0) |
|||
{ |
|||
static::$_instance[$k]->select($attr['db_id']); |
|||
} |
|||
} |
|||
|
|||
return static::$_instance[$k]; |
|||
} |
|||
|
|||
private function __clone(){} |
|||
|
|||
/** |
|||
* 执行原生的redis操作 |
|||
* @return \Redis |
|||
*/ |
|||
public function getRedis() |
|||
{ |
|||
return $this->redis; |
|||
} |
|||
|
|||
/*****************hash表操作函数*******************/ |
|||
|
|||
/** |
|||
* 得到hash表中一个字段的值 |
|||
* @param string $key 缓存key |
|||
* @param string $field 字段 |
|||
* @return string|false |
|||
*/ |
|||
public function hGet($key,$field) |
|||
{ |
|||
return $this->redis->hGet($key,$field); |
|||
} |
|||
|
|||
/** |
|||
* 为hash表设定一个字段的值 |
|||
* @param string $key 缓存key |
|||
* @param string $field 字段 |
|||
* @param string $value 值。 |
|||
* @return bool |
|||
*/ |
|||
public function hSet($key,$field,$value) |
|||
{ |
|||
return $this->redis->hSet($key,$field,$value); |
|||
} |
|||
|
|||
/** |
|||
* 判断hash表中,指定field是不是存在 |
|||
* @param string $key 缓存key |
|||
* @param string $field 字段 |
|||
* @return bool |
|||
*/ |
|||
public function hExists($key,$field) |
|||
{ |
|||
return $this->redis->hExists($key,$field); |
|||
} |
|||
|
|||
/** |
|||
* 删除hash表中指定字段 ,支持批量删除 |
|||
* @param string $key 缓存key |
|||
* @param string $field 字段 |
|||
* @return int |
|||
*/ |
|||
public function hdel($key,$field) |
|||
{ |
|||
$fieldArr=explode(',',$field); |
|||
$delNum=0; |
|||
|
|||
foreach($fieldArr as $row) |
|||
{ |
|||
$row=trim($row); |
|||
$delNum+=$this->redis->hDel($key,$row); |
|||
} |
|||
|
|||
return $delNum; |
|||
} |
|||
|
|||
/** |
|||
* 返回hash表元素个数 |
|||
* @param string $key 缓存key |
|||
* @return int|bool |
|||
*/ |
|||
public function hLen($key) |
|||
{ |
|||
return $this->redis->hLen($key); |
|||
} |
|||
|
|||
/** |
|||
* 为hash表设定一个字段的值,如果字段存在,返回false |
|||
* @param string $key 缓存key |
|||
* @param string $field 字段 |
|||
* @param string $value 值。 |
|||
* @return bool |
|||
*/ |
|||
public function hSetNx($key,$field,$value) |
|||
{ |
|||
return $this->redis->hSetNx($key,$field,$value); |
|||
} |
|||
|
|||
/** |
|||
* 为hash表多个字段设定值。 |
|||
* @param string $key |
|||
* @param array $value |
|||
* @return array|bool |
|||
*/ |
|||
public function hMset($key,$value) |
|||
{ |
|||
if(!is_array($value)) |
|||
return false; |
|||
return $this->redis->hMset($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 为hash表多个字段设定值。 |
|||
* @param string $key |
|||
* @param array|string $value string以','号分隔字段 |
|||
* @return array|bool |
|||
*/ |
|||
public function hMget($key,$field) |
|||
{ |
|||
if(!is_array($field)) |
|||
$field=explode(',', $field); |
|||
return $this->redis->hMget($key,$field); |
|||
} |
|||
|
|||
/** |
|||
* 为hash表设这累加,可以负数 |
|||
* @param string $key |
|||
* @param int $field |
|||
* @param string $value |
|||
* @return bool |
|||
*/ |
|||
public function hIncrBy($key,$field,$value) |
|||
{ |
|||
$value=intval($value); |
|||
return $this->redis->hIncrBy($key,$field,$value); |
|||
} |
|||
|
|||
/** |
|||
* 返回所有hash表的所有字段 |
|||
* @param string $key |
|||
* @return array|bool |
|||
*/ |
|||
public function hKeys($key) |
|||
{ |
|||
return $this->redis->hKeys($key); |
|||
} |
|||
|
|||
/** |
|||
* 返回所有hash表的字段值,为一个索引数组 |
|||
* @param string $key |
|||
* @return array|bool |
|||
*/ |
|||
public function hVals($key) |
|||
{ |
|||
return $this->redis->hVals($key); |
|||
} |
|||
|
|||
/** |
|||
* 返回所有hash表的字段值,为一个关联数组 |
|||
* @param string $key |
|||
* @return array|bool |
|||
*/ |
|||
public function hGetAll($key) |
|||
{ |
|||
return $this->redis->hGetAll($key); |
|||
} |
|||
|
|||
/*********************有序集合操作*********************/ |
|||
|
|||
/** |
|||
* 给当前集合添加一个元素 |
|||
* 如果value已经存在,会更新order的值。 |
|||
* @param string $key |
|||
* @param string $order 序号 |
|||
* @param string $value 值 |
|||
* @return bool |
|||
*/ |
|||
public function zAdd($key,$order,$value) |
|||
{ |
|||
return $this->redis->zAdd($key,$order,$value); |
|||
} |
|||
|
|||
/** |
|||
* 给$value成员的order值,增加$num,可以为负数 |
|||
* @param string $key |
|||
* @param string $num 序号 |
|||
* @param string $value 值 |
|||
* @return 返回新的order |
|||
*/ |
|||
public function zinCry($key,$num,$value) |
|||
{ |
|||
return $this->redis->zinCry($key,$num,$value); |
|||
} |
|||
|
|||
/** |
|||
* 删除值为value的元素 |
|||
* @param string $key |
|||
* @param stirng $value |
|||
* @return bool |
|||
*/ |
|||
public function zRem($key,$value) |
|||
{ |
|||
return $this->redis->zRem($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 集合以order递增排列后,0表示第一个元素,-1表示最后一个元素 |
|||
* @param string $key |
|||
* @param int $start |
|||
* @param int $end |
|||
* @return array|bool |
|||
*/ |
|||
public function zRange($key,$start,$end) |
|||
{ |
|||
return $this->redis->zRange($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* 集合以order递减排列后,0表示第一个元素,-1表示最后一个元素 |
|||
* @param string $key |
|||
* @param int $start |
|||
* @param int $end |
|||
* @return array|bool |
|||
*/ |
|||
public function zRevRange($key,$start,$end) |
|||
{ |
|||
return $this->redis->zRevRange($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* 集合以order递增排列后,返回指定order之间的元素。 |
|||
* min和max可以是-inf和+inf 表示最大值,最小值 |
|||
* @param string $key |
|||
* @param int $start |
|||
* @param int $end |
|||
* @package array $option 参数 |
|||
* withscores=>true,表示数组下标为Order值,默认返回索引数组 |
|||
* limit=>array(0,1) 表示从0开始,取一条记录。 |
|||
* @return array|bool |
|||
*/ |
|||
public function zRangeByScore($key,$start='-inf',$end="+inf",$option=array()) |
|||
{ |
|||
return $this->redis->zRangeByScore($key,$start,$end,$option); |
|||
} |
|||
|
|||
/** |
|||
* 集合以order递减排列后,返回指定order之间的元素。 |
|||
* min和max可以是-inf和+inf 表示最大值,最小值 |
|||
* @param string $key |
|||
* @param int $start |
|||
* @param int $end |
|||
* @package array $option 参数 |
|||
* withscores=>true,表示数组下标为Order值,默认返回索引数组 |
|||
* limit=>array(0,1) 表示从0开始,取一条记录。 |
|||
* @return array|bool |
|||
*/ |
|||
public function zRevRangeByScore($key,$start='-inf',$end="+inf",$option=array()) |
|||
{ |
|||
return $this->redis->zRevRangeByScore($key,$start,$end,$option); |
|||
} |
|||
|
|||
/** |
|||
* 返回order值在start end之间的数量 |
|||
* @param unknown $key |
|||
* @param unknown $start |
|||
* @param unknown $end |
|||
*/ |
|||
public function zCount($key,$start,$end) |
|||
{ |
|||
return $this->redis->zCount($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* 返回值为value的order值 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function zScore($key,$value) |
|||
{ |
|||
return $this->redis->zScore($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 返回集合以score递增加排序后,指定成员的排序号,从0开始。 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function zRank($key,$value) |
|||
{ |
|||
return $this->redis->zRank($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 返回集合以score递增加排序后,指定成员的排序号,从0开始。 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function zRevRank($key,$value) |
|||
{ |
|||
return $this->redis->zRevRank($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 删除集合中,score值在start end之间的元素 包括start end |
|||
* min和max可以是-inf和+inf 表示最大值,最小值 |
|||
* @param unknown $key |
|||
* @param unknown $start |
|||
* @param unknown $end |
|||
* @return 删除成员的数量。 |
|||
*/ |
|||
public function zRemRangeByScore($key,$start,$end) |
|||
{ |
|||
return $this->redis->zRemRangeByScore($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* 返回集合元素个数。 |
|||
* @param unknown $key |
|||
*/ |
|||
public function zCard($key) |
|||
{ |
|||
return $this->redis->zCard($key); |
|||
} |
|||
/*********************队列操作命令************************/ |
|||
|
|||
/** |
|||
* 在队列尾部插入一个元素 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
* 返回队列长度 |
|||
*/ |
|||
public function rPush($key,$value) |
|||
{ |
|||
return $this->redis->rPush($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 在队列尾部插入一个元素 如果key不存在,什么也不做 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
* 返回队列长度 |
|||
*/ |
|||
public function rPushx($key,$value) |
|||
{ |
|||
return $this->redis->rPushx($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 在队列头部插入一个元素 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
* 返回队列长度 |
|||
*/ |
|||
public function lPush($key,$value) |
|||
{ |
|||
return $this->redis->lPush($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 在队列头插入一个元素 如果key不存在,什么也不做 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
* 返回队列长度 |
|||
*/ |
|||
public function lPushx($key,$value) |
|||
{ |
|||
return $this->redis->lPushx($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 返回队列长度 |
|||
* @param unknown $key |
|||
*/ |
|||
public function lLen($key) |
|||
{ |
|||
return $this->redis->lLen($key); |
|||
} |
|||
|
|||
/** |
|||
* 返回队列指定区间的元素 |
|||
* @param unknown $key |
|||
* @param unknown $start |
|||
* @param unknown $end |
|||
*/ |
|||
public function lRange($key,$start,$end) |
|||
{ |
|||
return $this->redis->lrange($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* 返回队列中指定索引的元素 |
|||
* @param unknown $key |
|||
* @param unknown $index |
|||
*/ |
|||
public function lIndex($key,$index) |
|||
{ |
|||
return $this->redis->lIndex($key,$index); |
|||
} |
|||
|
|||
/** |
|||
* 设定队列中指定index的值。 |
|||
* @param unknown $key |
|||
* @param unknown $index |
|||
* @param unknown $value |
|||
*/ |
|||
public function lSet($key,$index,$value) |
|||
{ |
|||
return $this->redis->lSet($key,$index,$value); |
|||
} |
|||
|
|||
/** |
|||
* 删除值为vaule的count个元素 |
|||
* PHP-REDIS扩展的数据顺序与命令的顺序不太一样,不知道是不是bug |
|||
* count>0 从尾部开始 |
|||
* >0 从头部开始 |
|||
* =0 删除全部 |
|||
* @param unknown $key |
|||
* @param unknown $count |
|||
* @param unknown $value |
|||
*/ |
|||
public function lRem($key,$count,$value) |
|||
{ |
|||
return $this->redis->lRem($key,$value,$count); |
|||
} |
|||
|
|||
/** |
|||
* 删除并返回队列中的头元素。 |
|||
* @param unknown $key |
|||
*/ |
|||
public function lPop($key) |
|||
{ |
|||
return $this->redis->lPop($key); |
|||
} |
|||
|
|||
/** |
|||
* 删除并返回队列中的尾元素 |
|||
* @param unknown $key |
|||
*/ |
|||
public function rPop($key) |
|||
{ |
|||
return $this->redis->rPop($key); |
|||
} |
|||
|
|||
/*************redis字符串操作命令*****************/ |
|||
|
|||
/** |
|||
* 设置一个key |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function set($key,$value) |
|||
{ |
|||
return $this->redis->set($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 得到一个key |
|||
* @param unknown $key |
|||
*/ |
|||
public function get($key) |
|||
{ |
|||
return $this->redis->get($key); |
|||
} |
|||
|
|||
/** |
|||
* 设置一个有过期时间的key |
|||
* @param unknown $key |
|||
* @param unknown $expire |
|||
* @param unknown $value |
|||
*/ |
|||
public function setex($key,$expire,$value) |
|||
{ |
|||
return $this->redis->setex($key,$expire,$value); |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 设置一个key,如果key存在,不做任何操作. |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function setnx($key,$value) |
|||
{ |
|||
return $this->redis->setnx($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* 批量设置key |
|||
* @param unknown $arr |
|||
*/ |
|||
public function mset($arr) |
|||
{ |
|||
return $this->redis->mset($arr); |
|||
} |
|||
|
|||
/*************redis 无序集合操作命令*****************/ |
|||
|
|||
/** |
|||
* 返回集合中所有元素 |
|||
* @param unknown $key |
|||
*/ |
|||
public function sMembers($key) |
|||
{ |
|||
return $this->redis->sMembers($key); |
|||
} |
|||
|
|||
/** |
|||
* 求2个集合的差集 |
|||
* @param unknown $key1 |
|||
* @param unknown $key2 |
|||
*/ |
|||
public function sDiff($key1,$key2) |
|||
{ |
|||
return $this->redis->sDiff($key1,$key2); |
|||
} |
|||
|
|||
/** |
|||
* 添加集合。由于版本问题,扩展不支持批量添加。这里做了封装 |
|||
* @param unknown $key |
|||
* @param string|array $value |
|||
*/ |
|||
public function sAdd($key,$value) |
|||
{ |
|||
if(!is_array($value)) |
|||
$arr=array($value); |
|||
else |
|||
$arr=$value; |
|||
foreach($arr as $row) |
|||
$this->redis->sAdd($key,$row); |
|||
} |
|||
|
|||
/** |
|||
* 返回无序集合的元素个数 |
|||
* @param unknown $key |
|||
*/ |
|||
public function scard($key) |
|||
{ |
|||
return $this->redis->scard($key); |
|||
} |
|||
|
|||
/** |
|||
* 从集合中删除一个元素 |
|||
* @param unknown $key |
|||
* @param unknown $value |
|||
*/ |
|||
public function srem($key,$value) |
|||
{ |
|||
return $this->redis->srem($key,$value); |
|||
} |
|||
|
|||
/*************redis管理操作命令*****************/ |
|||
|
|||
/** |
|||
* 选择数据库 |
|||
* @param int $dbId 数据库ID号 |
|||
* @return bool |
|||
*/ |
|||
public function select($dbId) |
|||
{ |
|||
$this->dbId=$dbId; |
|||
return $this->redis->select($dbId); |
|||
} |
|||
|
|||
/** |
|||
* 清空当前数据库 |
|||
* @return bool |
|||
*/ |
|||
public function flushDB() |
|||
{ |
|||
return $this->redis->flushDB(); |
|||
} |
|||
|
|||
/** |
|||
* 返回当前库状态 |
|||
* @return array |
|||
*/ |
|||
public function info() |
|||
{ |
|||
return $this->redis->info(); |
|||
} |
|||
|
|||
/** |
|||
* 同步保存数据到磁盘 |
|||
*/ |
|||
public function save() |
|||
{ |
|||
return $this->redis->save(); |
|||
} |
|||
|
|||
/** |
|||
* 异步保存数据到磁盘 |
|||
*/ |
|||
public function bgSave() |
|||
{ |
|||
return $this->redis->bgSave(); |
|||
} |
|||
|
|||
/** |
|||
* 返回最后保存到磁盘的时间 |
|||
*/ |
|||
public function lastSave() |
|||
{ |
|||
return $this->redis->lastSave(); |
|||
} |
|||
|
|||
/** |
|||
* 返回key,支持*多个字符,?一个字符 |
|||
* 只有* 表示全部 |
|||
* @param string $key |
|||
* @return array |
|||
*/ |
|||
public function keys($key) |
|||
{ |
|||
return $this->redis->keys($key); |
|||
} |
|||
|
|||
/** |
|||
* 删除指定key |
|||
* @param unknown $key |
|||
*/ |
|||
public function del($key) |
|||
{ |
|||
return $this->redis->del($key); |
|||
} |
|||
|
|||
/** |
|||
* 判断一个key值是不是存在 |
|||
* @param unknown $key |
|||
*/ |
|||
public function exists($key) |
|||
{ |
|||
return $this->redis->exists($key); |
|||
} |
|||
|
|||
/** |
|||
* 为一个key设定过期时间 单位为秒 |
|||
* @param unknown $key |
|||
* @param unknown $expire |
|||
*/ |
|||
public function expire($key,$expire) |
|||
{ |
|||
return $this->redis->expire($key,$expire); |
|||
} |
|||
|
|||
/** |
|||
* 返回一个key还有多久过期,单位秒 |
|||
* @param unknown $key |
|||
*/ |
|||
public function ttl($key) |
|||
{ |
|||
return $this->redis->ttl($key); |
|||
} |
|||
|
|||
/** |
|||
* 设定一个key什么时候过期,time为一个时间戳 |
|||
* @param unknown $key |
|||
* @param unknown $time |
|||
*/ |
|||
public function exprieAt($key,$time) |
|||
{ |
|||
return $this->redis->expireAt($key,$time); |
|||
} |
|||
|
|||
/** |
|||
* 关闭服务器链接 |
|||
*/ |
|||
public function close() |
|||
{ |
|||
return $this->redis->close(); |
|||
} |
|||
|
|||
/** |
|||
* 关闭所有连接 |
|||
*/ |
|||
public static function closeAll() |
|||
{ |
|||
foreach(static::$_instance as $o) |
|||
{ |
|||
if($o instanceof self) |
|||
$o->close(); |
|||
} |
|||
} |
|||
|
|||
/** 这里不关闭连接,因为session写入会在所有对象销毁之后。 |
|||
public function __destruct() |
|||
{ |
|||
return $this->redis->close(); |
|||
} |
|||
**/ |
|||
/** |
|||
* 返回当前数据库key数量 |
|||
*/ |
|||
public function dbSize() |
|||
{ |
|||
return $this->redis->dbSize(); |
|||
} |
|||
|
|||
/** |
|||
* 返回一个随机key |
|||
*/ |
|||
public function randomKey() |
|||
{ |
|||
return $this->redis->randomKey(); |
|||
} |
|||
|
|||
/** |
|||
* 得到当前数据库ID |
|||
* @return int |
|||
*/ |
|||
public function getDbId() |
|||
{ |
|||
return $this->dbId; |
|||
} |
|||
|
|||
/** |
|||
* 返回当前密码 |
|||
*/ |
|||
public function getAuth() |
|||
{ |
|||
return $this->auth; |
|||
} |
|||
|
|||
public function getHost() |
|||
{ |
|||
return $this->host; |
|||
} |
|||
|
|||
public function getPort() |
|||
{ |
|||
return $this->port; |
|||
} |
|||
|
|||
public function getConnInfo() |
|||
{ |
|||
return array( |
|||
'host'=>$this->host, |
|||
'port'=>$this->port, |
|||
'auth'=>$this->auth |
|||
); |
|||
} |
|||
/*********************事务的相关方法************************/ |
|||
|
|||
/** |
|||
* 监控key,就是一个或多个key添加一个乐观锁 |
|||
* 在此期间如果key的值如果发生的改变,刚不能为key设定值 |
|||
* 可以重新取得Key的值。 |
|||
* @param unknown $key |
|||
*/ |
|||
public function watch($key) |
|||
{ |
|||
return $this->redis->watch($key); |
|||
} |
|||
|
|||
/** |
|||
* 取消当前链接对所有key的watch |
|||
* EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行 UNWATCH 了 |
|||
*/ |
|||
public function unwatch() |
|||
{ |
|||
return $this->redis->unwatch(); |
|||
} |
|||
|
|||
/** |
|||
* 开启一个事务 |
|||
* 事务的调用有两种模式Redis::MULTI和Redis::PIPELINE, |
|||
* 默认是Redis::MULTI模式, |
|||
* Redis::PIPELINE管道模式速度更快,但没有任何保证原子性有可能造成数据的丢失 |
|||
*/ |
|||
public function multi($type=\Redis::MULTI) |
|||
{ |
|||
return $this->redis->multi($type); |
|||
} |
|||
|
|||
/** |
|||
* 执行一个事务 |
|||
* 收到 EXEC 命令后进入事务执行,事务中任意命令执行失败,其余的命令依然被执行 |
|||
*/ |
|||
public function exec() |
|||
{ |
|||
return $this->redis->exec(); |
|||
} |
|||
|
|||
/** |
|||
* 回滚一个事务 |
|||
*/ |
|||
public function discard() |
|||
{ |
|||
return $this->redis->discard(); |
|||
} |
|||
|
|||
/** |
|||
* 测试当前链接是不是已经失效 |
|||
* 没有失效返回+PONG |
|||
* 失效返回false |
|||
*/ |
|||
public function ping() |
|||
{ |
|||
return $this->redis->ping(); |
|||
} |
|||
|
|||
public function auth($auth) |
|||
{ |
|||
return $this->redis->auth($auth); |
|||
} |
|||
/*********************自定义的方法,用于简化操作************************/ |
|||
|
|||
/** |
|||
* 得到一组的ID号 |
|||
* @param unknown $prefix |
|||
* @param unknown $ids |
|||
*/ |
|||
public function hashAll($prefix,$ids) |
|||
{ |
|||
if($ids==false) |
|||
return false; |
|||
if(is_string($ids)) |
|||
$ids=explode(',', $ids); |
|||
$arr=array(); |
|||
foreach($ids as $id) |
|||
{ |
|||
$key=$prefix.'.'.$id; |
|||
$res=$this->hGetAll($key); |
|||
if($res!=false) |
|||
$arr[]=$res; |
|||
} |
|||
|
|||
return $arr; |
|||
} |
|||
|
|||
/** |
|||
* 生成一条消息,放在redis数据库中。使用0号库。 |
|||
* @param string|array $msg |
|||
*/ |
|||
public function pushMessage($lkey,$msg) |
|||
{ |
|||
if(is_array($msg)){ |
|||
$msg = json_encode($msg); |
|||
} |
|||
$key = md5($msg); |
|||
|
|||
//如果消息已经存在,删除旧消息,已当前消息为准
|
|||
//echo $n=$this->lRem($lkey, 0, $key)."\n";
|
|||
//重新设置新消息
|
|||
$this->lPush($lkey, $key); |
|||
$this->setex($key, 3600, $msg); |
|||
return $key; |
|||
} |
|||
|
|||
|
|||
/** |
|||
* 得到条批量删除key的命令 |
|||
* @param unknown $keys |
|||
* @param unknown $dbId |
|||
*/ |
|||
public function delKeys($keys,$dbId) |
|||
{ |
|||
$redisInfo=$this->getConnInfo(); |
|||
$cmdArr=array( |
|||
'redis-cli', |
|||
'-a', |
|||
$redisInfo['auth'], |
|||
'-h', |
|||
$redisInfo['host'], |
|||
'-p', |
|||
$redisInfo['port'], |
|||
'-n', |
|||
$dbId, |
|||
); |
|||
$redisStr=implode(' ', $cmdArr); |
|||
$cmd="{$redisStr} KEYS \"{$keys}\" | xargs {$redisStr} del"; |
|||
return $cmd; |
|||
} |
|||
} |
@ -0,0 +1,398 @@ |
|||
<?php |
|||
namespace App\Common; |
|||
|
|||
/** |
|||
* Redis 操作,支持 Master/Slave 的负载集群 |
|||
* |
|||
* @author jackluo |
|||
*/ |
|||
class RedisCluster |
|||
{ |
|||
// 是否使用 M/S 的读写集群方案
|
|||
private $_isUseCluster = false; |
|||
|
|||
// Slave 句柄标记
|
|||
private $_sn = 0; |
|||
|
|||
// 服务器连接句柄
|
|||
private $_linkHandle = array( |
|||
'master'=>null,// 只支持一台 Master
|
|||
'slave'=>array(),// 可以有多台 Slave
|
|||
); |
|||
|
|||
/** |
|||
* 构造函数 |
|||
* |
|||
* @param boolean $isUseCluster 是否采用 M/S 方案 |
|||
*/ |
|||
public function __construct($isUseCluster=false) |
|||
{ |
|||
$this->_isUseCluster = $isUseCluster; |
|||
} |
|||
|
|||
/** |
|||
* 连接服务器,注意:这里使用长连接,提高效率,但不会自动关闭 |
|||
* |
|||
* @param array $config Redis服务器配置 |
|||
* @param boolean $isMaster 当前添加的服务器是否为 Master 服务器 |
|||
* @return boolean |
|||
*/ |
|||
public function connect($config=array('host'=>'127.0.0.1','port'=>6379), $isMaster=true) |
|||
{ |
|||
// default port
|
|||
if(!isset($config['port'])) |
|||
{ |
|||
$config['port'] = 6379; |
|||
} |
|||
|
|||
// 设置 Master 连接
|
|||
if($isMaster) |
|||
{ |
|||
$this->_linkHandle['master'] = new Redis(); |
|||
$ret = $this->_linkHandle['master']->pconnect($config['host'],$config['port']); |
|||
} |
|||
else |
|||
{ |
|||
// 多个 Slave 连接
|
|||
$this->_linkHandle['slave'][$this->_sn] = new Redis(); |
|||
$ret = $this->_linkHandle['slave'][$this->_sn]->pconnect($config['host'],$config['port']); |
|||
++$this->_sn; |
|||
} |
|||
|
|||
return $ret; |
|||
} |
|||
|
|||
/** |
|||
* 关闭连接 |
|||
* |
|||
* @param int $flag 关闭选择 0:关闭 Master 1:关闭 Slave 2:关闭所有 |
|||
* @return boolean |
|||
*/ |
|||
public function close($flag=2){ |
|||
switch($flag){ |
|||
// 关闭 Master
|
|||
case 0: |
|||
$this->getRedis()->close(); |
|||
break; |
|||
// 关闭 Slave
|
|||
case 1: |
|||
for($i=0; $i<$this->_sn; ++$i){ |
|||
$this->_linkHandle['slave'][$i]->close(); |
|||
} |
|||
break; |
|||
// 关闭所有
|
|||
case 1: |
|||
$this->getRedis()->close(); |
|||
for($i=0; $i<$this->_sn; ++$i){ |
|||
$this->_linkHandle['slave'][$i]->close(); |
|||
} |
|||
break; |
|||
} |
|||
return true; |
|||
} |
|||
|
|||
/** |
|||
* 得到 Redis 原始对象可以有更多的操作 |
|||
* |
|||
* @param boolean $isMaster 返回服务器的类型 true:返回Master false:返回Slave |
|||
* @param boolean $slaveOne 返回的Slave选择 true:负载均衡随机返回一个Slave选择 false:返回所有的Slave选择 |
|||
* @return redis object |
|||
*/ |
|||
public function getRedis($isMaster=true,$slaveOne=true){ |
|||
// 只返回 Master
|
|||
if($isMaster){ |
|||
return $this->_linkHandle['master']; |
|||
}else{ |
|||
return $slaveOne ? $this->_getSlaveRedis() : $this->_linkHandle['slave']; |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 写缓存 |
|||
* |
|||
* @param string $key 组存KEY |
|||
* @param string $value 缓存值 |
|||
* @param int $expire 过期时间, 0:表示无过期时间 |
|||
*/ |
|||
public function set($key, $value, $expire=0){ |
|||
// 永不超时
|
|||
if($expire == 0){ |
|||
$ret = $this->getRedis()->set($key, $value); |
|||
}else{ |
|||
$ret = $this->getRedis()->setex($key, $expire, $value); |
|||
} |
|||
return $ret; |
|||
} |
|||
|
|||
/** |
|||
* 读缓存 |
|||
* |
|||
* @param string $key 缓存KEY,支持一次取多个 $key = array('key1','key2') |
|||
* @return string || boolean 失败返回 false, 成功返回字符串 |
|||
*/ |
|||
public function get($key){ |
|||
// 是否一次取多个值
|
|||
$func = is_array($key) ? 'mGet' : 'get'; |
|||
// 没有使用M/S
|
|||
if(! $this->_isUseCluster){ |
|||
return $this->getRedis()->{$func}($key); |
|||
} |
|||
// 使用了 M/S
|
|||
return $this->_getSlaveRedis()->{$func}($key); |
|||
} |
|||
|
|||
|
|||
/* |
|||
// magic function
|
|||
public function __call($name,$arguments){ |
|||
return call_user_func($name,$arguments); |
|||
} |
|||
*/ |
|||
/** |
|||
* 条件形式设置缓存,如果 key 不存时就设置,存在时设置失败 |
|||
* |
|||
* @param string $key 缓存KEY |
|||
* @param string $value 缓存值 |
|||
* @return boolean |
|||
*/ |
|||
public function setnx($key, $value){ |
|||
return $this->getRedis()->setnx($key, $value); |
|||
} |
|||
|
|||
/** |
|||
* 删除缓存 |
|||
* |
|||
* @param string || array $key 缓存KEY,支持单个健:"key1" 或多个健:array('key1','key2') |
|||
* @return int 删除的健的数量 |
|||
*/ |
|||
public function remove($key){ |
|||
// $key => "key1" || array('key1','key2')
|
|||
return $this->getRedis()->delete($key); |
|||
} |
|||
|
|||
/** |
|||
* 值加加操作,类似 ++$i ,如果 key 不存在时自动设置为 0 后进行加加操作 |
|||
* |
|||
* @param string $key 缓存KEY |
|||
* @param int $default 操作时的默认值 |
|||
* @return int 操作后的值 |
|||
*/ |
|||
public function incr($key,$default=1){ |
|||
if($default == 1){ |
|||
return $this->getRedis()->incr($key); |
|||
}else{ |
|||
return $this->getRedis()->incrBy($key, $default); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 值减减操作,类似 --$i ,如果 key 不存在时自动设置为 0 后进行减减操作 |
|||
* |
|||
* @param string $key 缓存KEY |
|||
* @param int $default 操作时的默认值 |
|||
* @return int 操作后的值 |
|||
*/ |
|||
public function decr($key,$default=1){ |
|||
if($default == 1){ |
|||
return $this->getRedis()->decr($key); |
|||
}else{ |
|||
return $this->getRedis()->decrBy($key, $default); |
|||
} |
|||
} |
|||
|
|||
/** |
|||
* 添空当前数据库 |
|||
* |
|||
* @return boolean |
|||
*/ |
|||
public function clear(){ |
|||
return $this->getRedis()->flushDB(); |
|||
} |
|||
|
|||
/* =================== 以下私有方法 =================== */ |
|||
|
|||
/** |
|||
* 随机 HASH 得到 Redis Slave 服务器句柄 |
|||
* |
|||
* @return redis object |
|||
*/ |
|||
private function _getSlaveRedis(){ |
|||
// 就一台 Slave 机直接返回
|
|||
if($this->_sn <= 1){ |
|||
return $this->_linkHandle['slave'][0]; |
|||
} |
|||
// 随机 Hash 得到 Slave 的句柄
|
|||
$hash = $this->_hashId(mt_rand(), $this->_sn); |
|||
return $this->_linkHandle['slave'][$hash]; |
|||
} |
|||
|
|||
/** |
|||
* 根据ID得到 hash 后 0~m-1 之间的值 |
|||
* |
|||
* @param string $id |
|||
* @param int $m |
|||
* @return int |
|||
*/ |
|||
private function _hashId($id,$m=10) |
|||
{ |
|||
//把字符串K转换为 0~m-1 之间的一个值作为对应记录的散列地址
|
|||
$k = md5($id); |
|||
$l = strlen($k); |
|||
$b = bin2hex($k); |
|||
$h = 0; |
|||
for($i=0;$i<$l;$i++) |
|||
{ |
|||
//相加模式HASH
|
|||
$h += substr($b,$i*2,2); |
|||
} |
|||
|
|||
$hash = ($h*1)%$m; |
|||
return $hash; |
|||
} |
|||
|
|||
/** |
|||
* lpush |
|||
*/ |
|||
public function lpush($key,$value) |
|||
{ |
|||
return $this->getRedis()->lpush($key,$value); |
|||
} |
|||
|
|||
/** |
|||
* add lpop |
|||
*/ |
|||
public function lpop($key) |
|||
{ |
|||
return $this->getRedis()->lpop($key); |
|||
} |
|||
|
|||
/** |
|||
* lrange |
|||
*/ |
|||
public function lrange($key,$start,$end) |
|||
{ |
|||
return $this->getRedis()->lrange($key,$start,$end); |
|||
} |
|||
|
|||
/** |
|||
* set hash opeation |
|||
*/ |
|||
public function hset($name,$key,$value) |
|||
{ |
|||
if(is_array($value)) |
|||
{ |
|||
return $this->getRedis()->hset($name,$key,serialize($value)); |
|||
} |
|||
|
|||
return $this->getRedis()->hset($name,$key,$value); |
|||
} |
|||
|
|||
/** |
|||
* get hash opeation |
|||
*/ |
|||
public function hget($name,$key = null,$serialize=true) |
|||
{ |
|||
if($key) |
|||
{ |
|||
$row = $this->getRedis()->hget($name,$key); |
|||
if($row && $serialize) |
|||
{ |
|||
unserialize($row); |
|||
} |
|||
|
|||
return $row; |
|||
} |
|||
|
|||
return $this->getRedis()->hgetAll($name); |
|||
} |
|||
|
|||
/** |
|||
* delete hash opeation |
|||
*/ |
|||
public function hdel($name,$key = null) |
|||
{ |
|||
if($key) |
|||
{ |
|||
return $this->getRedis()->hdel($name,$key); |
|||
} |
|||
|
|||
return $this->getRedis()->hdel($name); |
|||
} |
|||
|
|||
/** |
|||
* Transaction start |
|||
*/ |
|||
public function multi() |
|||
{ |
|||
return $this->getRedis()->multi(); |
|||
} |
|||
|
|||
/** |
|||
* Transaction send |
|||
*/ |
|||
public function exec() |
|||
{ |
|||
return $this->getRedis()->exec(); |
|||
} |
|||
}// End Class
|
|||
|
|||
// ================= TEST DEMO =================
|
|||
|
|||
// 只有一台 Redis 的应用
|
|||
/* $redis = new RedisCluster(); |
|||
$redis->connect(array('host'=>'127.0.0.1','port'=>6379)); |
|||
|
|||
|
|||
//*
|
|||
$cron_id = 10001; |
|||
$CRON_KEY = 'CRON_LIST'; //
|
|||
$PHONE_KEY = 'PHONE_LIST:'.$cron_id;//
|
|||
|
|||
//cron info
|
|||
$cron = $redis->hget($CRON_KEY,$cron_id); |
|||
if(empty($cron)){ |
|||
|
|||
$cron = array('id'=>10,'name'=>'jackluo');//mysql data
|
|||
$redis->hset($CRON_KEY,$cron_id,$cron); // set redis
|
|||
} |
|||
//phone list
|
|||
$phone_list = $redis->lrange($PHONE_KEY,0,-1); |
|||
print_r($phone_list); |
|||
if(empty($phone_list)){ |
|||
$phone_list =explode(',','13228191831,18608041585'); //mysql data
|
|||
//join list
|
|||
if($phone_list){ |
|||
$redis->multi(); |
|||
foreach ($phone_list as $phone) { |
|||
$redis->lpush($PHONE_KEY,$phone); |
|||
} |
|||
$redis->exec(); |
|||
} |
|||
} |
|||
|
|||
print_r($phone_list); */ |
|||
|
|||
|
|||
/*$list = $redis->hget($cron_list,); |
|||
|
|||
var_dump($list);*/ |
|||
//*/
|
|||
|
|||
|
|||
//$redis->set('id',35);
|
|||
|
|||
/* |
|||
$redis->lpush('test','1111'); |
|||
$redis->lpush('test','2222'); |
|||
$redis->lpush('test','3333'); |
|||
|
|||
$list = $redis->lrange('test',0,-1); |
|||
print_r($list); |
|||
$lpop = $redis->lpop('test'); |
|||
print_r($lpop); |
|||
$lpop = $redis->lpop('test'); |
|||
print_r($lpop); |
|||
$lpop = $redis->lpop('test'); |
|||
print_r($lpop); |
|||
*/ |
|||
// var_dump($redis->get('id'));
|
53
lqycms.sql
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
Binary file not shown.
Before Width: 150 | Height: 80 | Size: 3.1 KiB After Width: 150 | Height: 80 | Size: 13 KiB |
@ -1 +1 @@ |
|||
<div id="footer" class="box">©丽杭汽车网 部分文章来源于网络,如果侵犯了您的权益,请联系我们。<div class="m-auto"><script>count_js();</script></div></div> |
|||
<div id="footer" class="box">©<?php echo sysconfig('CMS_WEBNAME'); ?> 部分文章来源于网络,如果侵犯了您的权益,请联系我们。<div class="m-auto"><script>count_js();</script></div></div>
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue