PHP实现操作redis的封装类完整实例


Posted in PHP onNovember 14, 2015

本文实例讲述了PHP实现操作redis的封装类。分享给大家供大家参考,具体如下:

<?php
/**
 * 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'));

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP 表单提交给自己
Jul 24 PHP
php 需要掌握的东西 不做浮躁的人
Dec 28 PHP
支持中文字母数字、自定义字体php验证码代码
Feb 27 PHP
PHP定时更新程序设计思路分享
Jun 10 PHP
PHP中的日期加减方法示例
Aug 21 PHP
PHP中使用Memache作为进程锁的操作类分享
Mar 30 PHP
Zend Framework教程之前端控制器Zend_Controller_Front用法详解
Mar 07 PHP
php简单中奖算法(实例)
Aug 15 PHP
php进程daemon化的正确实现方法
Sep 06 PHP
php面试实现反射注入的详细方法
Sep 30 PHP
laravel 多图上传及图片的存储例子
Oct 14 PHP
PHPExcel实现的读取多工作表操作示例
Apr 14 PHP
php实现的递归提成方案实例
Nov 14 #PHP
PHP使用Pthread实现的多线程操作实例
Nov 14 #PHP
开启PHP Static 关键字之旅模式
Nov 13 #PHP
php正则表达式学习笔记
Nov 13 #PHP
php邮箱地址正则表达式验证
Nov 13 #PHP
合格的PHP程序员必备技能
Nov 13 #PHP
PHP基于yii框架实现生成ICO图标
Nov 13 #PHP
You might like
调试一段PHP程序时遇到的三个问题
2012/01/17 PHP
PHP通过session id 实现session共享和登录验证的代码
2012/06/03 PHP
PHP给源代码加密的几种方法汇总(推荐)
2018/02/06 PHP
PHP+Ajax实现的检测用户名功能简单示例
2019/02/12 PHP
php设计模式之职责链模式实例分析【星际争霸游戏案例】
2020/03/27 PHP
jquery 双色表格实现代码
2009/12/08 Javascript
10个基于jQuery或JavaScript的WYSIWYG 编辑器整理
2010/05/06 Javascript
JS中怎样判断undefined(比较不错的方法)
2014/03/27 Javascript
单击和双击事件的冲突处理示例代码
2014/04/03 Javascript
js获取字符串最后一位方法汇总
2014/11/13 Javascript
完美兼容IE,chrome,ff的设为首页、加入收藏及保存到桌面js代码
2014/12/17 Javascript
JavaScript采用递归算法计算阶乘实例
2015/08/04 Javascript
JS公共小方法之判断对象是否为domElement的实例
2016/11/25 Javascript
JS中事件冒泡和事件捕获介绍
2016/12/13 Javascript
vue实现简单实时汇率计算功能
2017/01/15 Javascript
jquery实现下拉框左右选择功能
2017/02/21 Javascript
JS获取一个表单字段中多条数据并转化为json格式
2017/10/17 Javascript
推荐10款扩展Web表单的JS插件
2017/12/25 Javascript
在Vue项目中引入腾讯验证码服务的教程
2018/04/03 Javascript
微信小程序实现美团菜单
2018/06/06 Javascript
vue interceptor 使用教程实例详解
2018/09/13 Javascript
小程序实现授权登陆的解决方案
2018/12/02 Javascript
微信小程序实现单选选项卡切换效果
2020/06/19 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
nodejs简单抓包工具使用详解
2019/08/23 NodeJs
python中根据字符串调用函数的实现方法
2016/06/12 Python
Python解析命令行读取参数--argparse模块使用方法
2018/01/23 Python
CentOS下Python3的安装及创建虚拟环境的方法
2018/11/28 Python
详解django+django-celery+celery的整合实战
2019/03/19 Python
opencv python在视屏上截图功能的实现
2020/03/05 Python
html5 canvas fillRect坐标和大小的问题解决方法
2014/03/26 HTML / CSS
HTML5中的拖放实现详解
2017/08/23 HTML / CSS
英国最大的专业户外零售商:Mountain Warehouse
2018/06/06 全球购物
Martinelli官方商店:西班牙皮鞋和高跟鞋品牌
2019/07/30 全球购物
计算机专业学生求职信分享
2013/12/15 职场文书
大学生安全教育心得体会
2016/01/15 职场文书