封装predis类
<?php
use Predis\Client;

/**
 * redis队列操作
 */
require 'predis/autoload.php';

class RedisHandle{

    private $ci;

    protected $_redis;

    const OPERATE_TIMES = 10;           //同一操作重复入队列限制次数

    public function __construct() {

        $this->ci = &get_instance();

        $this->ci->load->config('redis.php');

        $configs = config_item('redis');

        $options = ['cluster' => 'redis'];

        try{

            $this->_redis = new Client($configs, $options);

        }catch (RedisException $e){

            log_message('error', 'Redis: Redis connection refused ('.$e->getMessage().')');
        }
    }
    /**
     * redis队列入栈操作
     * 
     * @param string $key
     * @param string $action
     * @param array $params
     * @param number $id
     * @param number $queueNums
     * @return boolean|integer 添加到队列后的返回值
     */
    public function push($key, $action, array $params, $id = 1, $queueNums = 1){

        $key = $this->_filter($key);

        $action = $this->_filter($action);

        if(!$key || !$action){

            log_message('error', 'Redis: params error.');

            return false;
        }

        $mod = $id%$queueNums;

        $key = strtolower($key.'_'.$mod);

        $params = json_encode($params);

        $val = $action.'||1||'.$params;

        return $this->_redis->lpush($key, $val);
    }
    /**
     * redis队列出栈操作
     * 
     * @param string $key
     * @return boolean|array 队列中取出的对应数据
     */
    public function pop(string $key){

        $key = $this->_filter($key);

        if(!$key){

            log_message('error', 'Redis: pop params error.');
            return false;
        }

        $key = strtolower($key);        

        $return_data = [];

        $data = $this->_redis->rpop($key);

        if(!$data){

            return false;
        }

        $val = $data;

        $data = explode('||', $data);

        $key_arr = ['action', 'times', 'params'];

        $return_data = array_combine($key_arr, $data);

        $return_data['params'] = json_decode($return_data['params']);

        $return_data['val'] = $val;

        return $return_data;
    }
    /**
     * redis队列重复入栈操作
     * 
     * @param string $key
     * @param string $val
     * @param string $reason
     * @return void|boolean|integer 执行重复入队列返回值
     */
    public function rePush(string $key, string $val, $reason = ''){

        $key = $this->_filter($key);

        if(!$key){

            log_message('error', 'Redis: pop params error.');

            return false;
        }

        $val_arr = explode('||', $val);

        $val_arr[1] += 1;

        if($val_arr[1] >= self::OPERATE_TIMES){

            $reason = empty($reason)?'请求失败次数频繁':$reason;

            $this->recordFailLog($key, $val, $val_arr[1], $reason);

            return ;
        }

        $key = strtolower($key);

        $val = implode('||', $val_arr);

        return $this->_redis->lpush($key, $val);
    }

    /**
     * 过滤字符串
     * 
     * @param string $str
     * @return boolean|mixed
     */
    private function _filter($str){

        $str = str_replace(' ', '', $str);

        if(empty($str)){

            return false;
        }

        return $str;
    }
    /**
     * 重复执行入队列次数过多后添加到失败日志表
     * 
     * @param string $key
     * @param string $val
     * @param number $times
     * @param string $msg
     * @return boolean 添加数据返回值
     */
    private function recordFailLog($key, $val, $times = self::OPERATE_TIMES, $msg = '请求次数超时'){

        $this->ci->load->model('SystemRedisFailLog');

        $time = time();

        $vals = explode('||', $val);

        $data = [];

        $data['redis_key'] = $key;
        $data['redis_action'] = $vals[0];
        $data['times'] = $times;
        $data['param'] = $val;
        $data['reason'] = $msg;
        $data['createtime'] = $time;
        $data['status'] = 0;

        $ret = $this->ci->SystemRedisFailLog->add($data);

        return $ret;
    }
    /**
     * 调试用
     * 
     * @param unknown $val
     * @return array
     */
    public function debug($val){

        $vals = explode('||', $val);

        $key_arr = ['action', 'times', 'params'];

        $return_data = array_combine($key_arr, $vals);

        $return_data['params'] = json_decode($return_data['params']);

        $return_data['val'] = $val;

        return $return_data;
    }
    /**
     * 添加redis数据缓存
     * 
     * @param string $key
     * @param unknown $value
     * @param number $ttl
     * @return boolean
     */
    public function hMset(string $key, $value, $ttl = 60){
        switch ($data_type = gettype($value))
        {
            case 'array':
            case 'object':
                $value = serialize($value);
                break;
            case 'boolean':
            case 'integer':
            case 'double': // Yes, 'double' is returned and NOT 'float'
            case 'string':
            case 'NULL':
                break;
            case 'resource':
            default:
                return false;
        }
        if ( ! $this->_redis->hmset($key, ['__ci_type' => $data_type, '__ci_value' => $value]))
        {
            return false;
        }
//         $this->_redis->expireat($key, time() + $ttl);

        return true;
    }
    /**
     * 获取redis缓存数据
     * 
     * @param string $key
     * @return boolean|mixed|boolean|unknown
     */
    public function hMget(string $key){

        $data = array_combine(
            ['__ci_type', '__ci_value'], $this->_redis->hmget($key, ['__ci_type', '__ci_value'])
        );

        if ( ! isset($data['__ci_type'], $data['__ci_value']) OR $data['__ci_value'] === false)
        {
            return false;
        }

        switch ($data['__ci_type'])
        {
            case 'array':
            case 'object':
                return unserialize($data['__ci_value']);
            case 'boolean':
            case 'integer':
            case 'double': // Yes, 'double' is returned and NOT 'float'
            case 'string':
            case 'NULL':
                return settype($data['__ci_value'], $data['__ci_type']) ? $data['__ci_value'] : false;
            case 'resource':
            default:
                return false;
        }
    }
    /**
     * 删除redis缓存数据
     * 
     * @param string $key
     * @return boolean
     */
    public function hMdel(string $key){

        return ($this->_redis->del($key) === 1);
    }

    /**
     * Determines if the driver is supported on this system.
     *
     * @return boolean
     */
    public function isSupported(): bool
    {
        return class_exists('\Predis\Client');
    }

}

阅读更多
文章标签: redis php
个人分类: php redis
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

封装predis类

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭