PHP使用Redis实战实录4:单例模式和面向过程操作redis的语法

news2024/9/23 3:18:11

PHP使用Redis实战实录系列

  • PHP使用Redis实战实录1:宝塔环境搭建、6379端口配置、Redis服务启动失败解决方案
  • PHP使用Redis实战实录2:Redis扩展方法和PHP连接Redis的多种方案
  • PHP使用Redis实战实录3:数据类型比较、大小限制和性能扩展
  • PHP使用Redis实战实录4:单例模式和面向过程操作redis的语法

面向过程操作redis的单例模式

  • 一、单例模式
    • 面对对象封装类(1)
    • 面对对象封装类(2)
  • 二、面向过程操作Redis
    • 1.php连接redis
    • 2.共性的运算归类
    • 3.Redis服务器操作
    • 4.String增删改操作
    • 5.List增删改操作
    • 6.set增删改操作
    • 7.Zset增删改操作
    • 8.Hash表结构增删改操作

在这里插入图片描述

为了应对不同的场景,redis分为是单机模式、主从模式、哨兵模式、集群模式四种模式。

  1. 单机模式(Standalone Mode):单机模式是最基本的 Redis 运行模式,它在单个实例上运行,不涉及复杂的集群配置。它被广泛用于开发和测试环境。

  2. 主从复制模式(Master-Slave Replication):主从复制模式通过将一个 Redis 实例设为主节点(Master)和一个或多个 Redis 实例设为从节点(Slave),实现数据的复制和备份。主节点负责写操作,而从节点复制主节点的数据,可以用于读操作或故障转移。

  3. 哨兵模式(Redis Sentinel Mode):Sentinel 是 Redis 提供的一个高可用解决方案,它通过在主从复制模式的基础上添加 Sentinel 进程来实现自动故障检测和故障切换。Sentinel 进程监视主节点和从节点的状态,并在主节点故障时自动将从节点升级为主节点。

  4. Cluster 模式(Redis Cluster Mode):集群模式是 Redis 最常用的分布式解决方案,它将多个 Redis 节点组成一个集群,每个节点负责存储一部分数据,并在节点之间自动进行数据分片和数据迁移。集群模式提供了高扩展性和高可用性。

这些运行模式可以根据需求选择合适的方案来使用 Redis,例如在开发和测试环境中使用单机模式,生产环境中使用主从复制或集群模式来提供高可用性和横向扩展能力。

一、单例模式

在 PHP 中使用 Redis 的单例模式可以确保在应用程序中只创建一个 Redis 连接实例,以便在多个地方共享该连接。

下面是一个简单的示例,展示如何使用单例模式实现 Redis 连接:

面对对象封装类(1)

class RedisSingleton
{
    private static $instance;
    private static $redis;

    private function __construct()
    {
        self::$redis = new Redis();
        self::$redis->connect('127.0.0.1', 6379);
        // 进行其他 Redis 相关的初始化操作
    }

    public static function getInstance()
    {
        if (!self::$instance) {
            self::$instance = new RedisSingleton();
        }
        return self::$instance;
    }

    public function getRedis()
    {
        return self::$redis;
    }
}

// 在应用程序中使用 Redis 单例模式
$redisSingleton = RedisSingleton::getInstance();
$redis = $redisSingleton->getRedis();

// 使用 $redis 进行操作,例如 $redis->get('key')、$redis->set('key', 'value') 等

面对对象封装类(2)

将redis变量放在配置文件,进行整体调用;

/*
 *  Redis操作类
 *  单例+支持长连接 模式
 */

class RedisSingleton
{
    const REDISTIMEOUT = 0; //超时
    private static $_instance = []; //类单例数组
    private $hash;
    private $redis; //redis连接句柄

    private function __construct($redis_config = [])
    {

        $this->redis = new Redis();
        $this->hash = $redis_config["redis_db"];

        if ($redis_config["redis_pconnect"]) {
            $this->redis->pconnect($redis_config["redis_host"], $redis_config["redis_port"], self::REDISTIMEOUT);
        } else {
            $this->redis->connect($redis_config["redis_host"], $redis_config["redis_port"], self::REDISTIMEOUT);
        }
        //设置连接密码
        if ($redis_config["redis_auth"]) {
            $this->redis->auth($redis_config["redis_auth"]);
        }
        //选择库 0-15
        $this->redis->select($this->hash);
    }

    //外部获取实例
    public static function getInstance($redis_config)
    {
        if (!isset(self::$_instance[$redis_config["redis_db"]])) {
            self::$_instance[$redis_config["redis_db"]] = new self($redis_config);
        }

        //防止挂掉
        try {
            self::$_instance[$redis_config["redis_db"]]->Ping() == 'Pong';
        } catch (Exception $e) {
            throw new Exception("连接错误");
        }
        return self::$_instance[$redis_config["redis_db"]];
    }

    //获取redis的连接实例
    public function getRedisConnect()
    {
        return $this->redis;
    }

    public function __call($method, $args)
    {
        return call_user_func_array([$this->redis, $method], $args);
    }


    /**
     * 关闭单例时做清理工作
     */
    public function __destruct()
    {
        $key = $this->hash;
        $this->redis->close();
        self::$_instance[$key] = null;
    }

    private function __clone()
    {
    }
}

$redis_config = [
    "redis_host" => "127.0.0.1",
    "redis_port" => "6379",
    "redis_db" => 0,
    "redis_auth" => "kYABzc8u3zNs7cq",
    "redis_pconnect" => 0
];

$redis = RedisSingleton::getInstance($redis_config);
$redis->set("hello", "world1");

在上述示例中,RedisSingleton 类的 getInstance 方法返回一个 Redis 单例实例。当需要使用 Redis 连接时,可以调用 getRedis 方法获取该实例的 Redis 连接对象。

通过这种方式,无论在应用程序中的哪个位置需要使用 Redis,都可以共享同一个 Redis 连接实例,避免了重复创建连接的开销。

二、面向过程操作Redis

1.php连接redis

/*1.Connection*/
$redis = new Redis();
$redis->connect('127.0.0.1',6379,1);//短链接,本地host,端口为6379,超过1秒放弃链接
$redis->open('127.0.0.1',6379,1);//短链接(同上)
$redis->pconnect('127.0.0.1',6379,1);//长链接,本地host,端口为6379,超过1秒放弃链接
$redis->popen('127.0.0.1',6379,1);//长链接(同上)
$redis->auth('password');//登录验证密码,返回【true | false】
$redis->select(0);//选择redis库,0~15 共16个库
$redis->close();//释放资源
$redis->ping(); //检查是否还再链接,[+pong]
$redis->ttl('key');//查看失效时间[-1 | timestamps]
$redis->persist('key');//移除失效时间[ 1 | 0]
$redis->sort('key',[$array]);//返回或保存给定列表、集合、有序集合key中经过排序的元素,$array为参数limit等 [array|false]

2.共性的运算归类

/*2.共性的运算归类*/
$redis->expire('key',10);//设置失效时间[true | false]
$redis->move('key',15);//把当前库中的key移动到15库中[0|1]
//string
$redis->strlen('key');//获取当前key的长度
$redis->append('key','string');//把string追加到key现有的value中[追加后的个数]
$redis->incr('key');//自增1,如不存在key,赋值为1(只对整数有效,存储以10进制64位,redis中为str)[new_num | false]
$redis->incrby('key',$num);//自增$num,不存在为赋值,值需为整数[new_num | false]
$redis->decr('key');//自减1,[new_num | false]
$redis->decrby('key',$num);//自减$num,[ new_num | false]
$redis->setex('key',10,'value');//key=value,有效期为10秒[true]
//list
$redis->llen('key');//返回列表key的长度,不存在key返回0, [ len | 0]
//set
$redis->scard('key');//返回集合key的基数(集合中元素的数量)。[num | 0]
$redis->sMove('key1', 'key2', 'member');//移动,将member元素从key1集合移动到key2集合。[1 | 0]
//Zset
$redis->zcard('key');//返回集合key的基数(集合中元素的数量)。[num | 0]
$redis->zcount('key',0,-1);//返回有序集key中,score值在min和max之间(默认包括score值等于min或max)的成员。[num | 0]
//hash
$redis->hexists('key','field');//查看hash中是否存在field,[1 | 0]
$redis->hincrby('key','field',$int_num);//为哈希表key中的域field的值加上量(+|-)num,[new_num | false]
$redis->hlen('key');//返回哈希表key中域的数量。[ num | 0]
 

3.Redis服务器操作

/*3.Server*/
$redis->dbSize();//返回当前库中的key的个数
$redis->flushAll();//清空整个redis[总true]
$redis->flushDB();//清空当前redis库[总true]
$redis->save();//同步??把数据存储到磁盘-dump.rdb[true]
$redis->bgsave();//异步??把数据存储到磁盘-dump.rdb[true]
$redis->info();//查询当前redis的状态 [verson:2.4.5....]
$redis->lastSave();//上次存储时间key的时间[timestamp]
$redis->watch('key','keyn');//监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断 [true]
$redis->unwatch('key','keyn');//取消监视一个(或多个) key [true]
$redis->multi(Redis::MULTI);//开启事务,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令在一个原子时间内执行。
$redis->multi(Redis::PIPELINE);//开启管道,事务块内的多条命令会按照先后顺序被放进一个队列当中,最后由 EXEC 命令在一个原子时间内执行。
$redis->exec();//执行所有事务块内的命令,;【事务块内所有命令的返回值,按命令执行的先后顺序排列,当操作被打断时,返回空值 false】

4.String增删改操作

/*4.String,键值对,创建更新同操作*/
$redis->setOption(Redis::OPT_PREFIX,'hf_');//设置表前缀为hf_
$redis->set('key',1);//设置key=aa value=1 [true]
$redis->mset($arr);//设置一个或多个键值[true]
$redis->setnx('key','value');//key=value,key存在返回false[|true]
$redis->get('key');//获取key [value]
$redis->mget($arr);//(string|arr),返回所查询键的值
$redis->del($key_arr);//(string|arr)删除key,支持数组批量删除【返回删除个数】
$redis->delete($key_str,$key2,$key3);//删除keys,[del_num]
$redis->getset('old_key','new_value');//先获得key的值,然后重新赋值,[old_value | false]

5.List增删改操作

/*5.List栈的结构,注意表头表尾,创建更新分开操作*/
$redis->lpush('key','value');//增,只能将一个值value插入到列表key的表头,不存在就创建 [列表的长度 |false]
$redis->rpush('key','value');//增,只能将一个值value插入到列表key的表尾 [列表的长度 |false]
$redis->lInsert('key', Redis::AFTER, 'value', 'new_value');//增,将值value插入到列表key当中,位于值value之前或之后。[new_len | false]
$redis->lpushx('key','value');//增,只能将一个值value插入到列表key的表头,不存在不创建 [列表的长度 |false]
$redis->rpushx('key','value');//增,只能将一个值value插入到列表key的表尾,不存在不创建 [列表的长度 |false]
$redis->lpop('key');//删,移除并返回列表key的头元素,[被删元素 | false]
$redis->rpop('key');//删,移除并返回列表key的尾元素,[被删元素 | false]
$redis->lrem('key','value',0);//删,根据参数count的值,移除列表中与参数value相等的元素count=(0|-n表头向尾|+n表尾向头移除n个value) [被移除的数量 | 0]
$redis->ltrim('key',start,end);//删,列表修剪,保留(start,end)之间的值 [true|false]
$redis->lset('key',index,'new_v');//改,从表头数,将列表key下标为第index的元素的值为new_v, [true | false]
$redis->lindex('key',index);//查,返回列表key中,下标为index的元素[value|false]
$redis->lrange('key',0,-1);//查,(start,stop|0,-1)返回列表key中指定区间内的元素,区间以偏移量start和stop指定。[array|false]

6.set增删改操作


/*6.Set,没有重复的member,创建更新同操作*/
$redis->sadd('key','value1','value2','valuen');//增,改,将一个或多个member元素加入到集合key当中,已经存在于集合的member元素将被忽略。[insert_num]
$redis->srem('key','value1','value2','valuen');//删,移除集合key中的一个或多个member元素,不存在的member元素会被忽略 [del_num | false]
$redis->smembers('key');//查,返回集合key中的所有成员 [array | '']
$redis->sismember('key','member');//判断member元素是否是集合key的成员 [1 | 0]
$redis->spop('key');//删,移除并返回集合中的一个随机元素 [member | false]
$redis->srandmember('key');//查,返回集合中的一个随机元素 [member | false]
$redis->sinter('key1','key2','keyn');//查,返回所有给定集合的交集 [array | false]
$redis->sunion('key1','key2','keyn');//查,返回所有给定集合的并集 [array | false]
$redis->sdiff('key1','key2','keyn');//查,返回所有给定集合的差集 [array | false]
 

7.Zset增删改操作

/*7.Zset,没有重复的member,有排序顺序,创建更新同操作*/
$redis->zAdd('key',$score1,$member1,$scoreN,$memberN);//增,改,将一个或多个member元素及其score值加入到有序集key当中。[num | 0]
$redis->zrem('key','member1','membern');//删,移除有序集key中的一个或多个成员,不存在的成员将被忽略。[del_num | 0]
$redis->zscore('key','member');//查,通过值反拿权 [num | null]
$redis->zrange('key',$start,$stop);//查,通过(score从小到大)【排序名次范围】拿member值,返回有序集key中,【指定区间内】的成员 [array | null]
$redis->zrevrange('key',$start,$stop);//查,通过(score从大到小)【排序名次范围】拿member值,返回有序集key中,【指定区间内】的成员 [array | null]
$redis->zrangebyscore('key',$min,$max[,$config]);//查,通过scroe权范围拿member值,返回有序集key中,指定区间内的(从小到大排)成员[array | null]
$redis->zrevrangebyscore('key',$max,$min[,$config]);//查,通过scroe权范围拿member值,返回有序集key中,指定区间内的(从大到小排)成员[array | null]
$redis->zrank('key','member');//查,通过member值查(score从小到大)排名结果中的【member排序名次】[order | null]
$redis->zrevrank('key','member');//查,通过member值查(score从大到小)排名结果中的【member排序名次】[order | null]
$redis->ZINTERSTORE();//交集
$redis->ZUNIONSTORE();//差集

8.Hash表结构增删改操作


/*8.Hash,表结构,创建更新同操作*/
$redis->hset('key','field','value');//增,改,将哈希表key中的域field的值设为value,不存在创建,存在就覆盖【1 | 0】
$redis->hget('key','field');//查,取值【value|false】
$arr = array('one'=>1,2,3);$arr2 = array('one',0,1);
$redis->hmset('key',$arr);//增,改,设置多值$arr为(索引|关联)数组,$arr[key]=field, [ true ]
$redis->hmget('key',$arr2);//查,获取指定下标的field,[$arr | false]
$redis->hgetall('key');//查,返回哈希表key中的所有域和值。[当key不存在时,返回一个空表]
$redis->hkeys('key');//查,返回哈希表key中的所有域。[当key不存在时,返回一个空表]
$redis->hvals('key');//查,返回哈希表key中的所有值。[当key不存在时,返回一个空表]
$redis->hdel('key',$arr2);//删,删除指定下标的field,不存在的域将被忽略,[num | false]

@漏刻有时

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/811345.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第六章 HL7 架构和可用工具 - 定义新的消息类型和结构类型

文章目录 第六章 HL7 架构和可用工具 - 定义新的消息类型和结构类型编辑数据结构和代码表 第六章 HL7 架构和可用工具 - 定义新的消息类型和结构类型 消息类型标识消息并与 HL7 MSH:9 字段中的值匹配。定义消息类型时,指定发送消息结构类型(可能与消息类…

OpenMP

官方文档:OpenMP | LLNL HPC Tutorials OpenMP总览 统一内存访问:OpenMP、Pthreads 非统一内存访问:MPI OpenMP与Pthread OpenMP原理 串行区到达并行区后会派生多个线程,并行区代码执行完后进行线程合并,剩下主线程 编…

SqueezeLM 的想法,压缩输入句子潜变量,生成下一句子

又搞了一段时间。还是感觉LongNet那种空洞注意力做编码器有搞头。 RetNet等AFT方法,直接生成太长的句子感觉有点难度,不过可以一句句生成,每次生成短句,这样感觉比较合适。 启发 受 MemroyTransformer 和 GLM 启发 想了一个类似…

大会第二日,精彩不停!LiveVideoStackCon 2023 上海站

历时四个月的精心筹备,LiveVideoStackCon 组委会与联席主席、出品人及评审团通力合作,90余位讲师对演讲内容的反复琢磨……只为呈现最专业的音视频技术盛会。 今日,以「沉浸新视界」为主题的LiveVideoStackCon 2023 上海站 音视频技术大会继续…

ACL原理

ACL原理 ACL是一种用于控制网络设备访问权限的技术,可以通过配置ACL来限制特定用户、应用程序或网络设备对网络资源的访问。 1、ACL(Access Control List) 2、ACL是一种包过滤技术。 3、ACL基于IP包头的IP地址、四层TCP/UDP头部的端口号、…

Flowable-服务-微服务任务

目录 定义图形标记XML内容界面操作 定义 Sc 任务不是 BPMN 2.0 规范定义的官方任务,在 Flowable 中,Sc 任务是作为一种特殊的服务 任务来实现的,主要调用springcloud的微服务使用。 图形标记 由于 Sc 任务不是 BPMN 2.0 规范的“官方”任务…

WebAgent-基于大型语言模型的代理程序

大型语言模型(LLM)可以解决多种自然语言任务,例如算术、常识、逻辑推理、问答、文本生成、交互式决策任务。最近,LLM在自主网络导航方面也取得了巨大成功,代理程序助HTML理解和多步推理的能力,通过控制计算…

【Linux多线程】详解线程控制、线程分离

线程互斥与同步 👸 理解线程🤴pthead_t🥷关于线程🦸‍♀️线程控制POSIX线程库线程ID及进程地址空间布局 🦸线程分离__thread关键字🦸‍♂️pthread_detach函数🦹‍♀️pthread_exit函数&#x…

[JavaWeb]SQL介绍-DDL-DML

SQL介绍-DDL-DML 一.SQL简介1.简介2.SQL通用语法3.SQL语言的分类 二.DDL-操作数据库与表1.DDL操作数据库2.DDL操作表①.查询表(Retrieve)②.创建表(Create)③.修改表(Update)④.删除表(Delete) 三.Navicat的安装与使用四.DML-操作表数据1.添加(Insert)2.修改(Update)3.删除(Del…

【C++】反向迭代器的模拟实现通用(可运用于vector,string,list等模拟容器)

文章目录 前言一、反向迭代器封装(reverseiterator)1.构造函数1解引用操作.3.->运算符重载4.前置,后置5.前置--,后置--6.不等号运算符重载7.完整代码 二、rbegin()以及rend()1.rb…

[nlp] TF-IDF算法介绍

(1)TF是词频(Term Frequency) 词频是文档中词出现的概率。 (2) IDF是逆向文件频率(Inverse Document Frequency) 包含词条的文档越少,IDF越大。

01-导数的定义_左导数和右导数

微积分 导数的定义 左导数与右导数、可导函数 趋近于 0 有两个方向,从左边趋向于 0 是左导数,反之是右导数 下面的绝对值函数的左导数和右导数不相同,一个-1 一个1,0 位置不可导 f(x)|x|, 导数可以理解为某点的斜率…

生命在于学习——指纹混淆技术学习

一、前言 本篇文章仅为学习笔记记录,不得用于违规用途。 本篇文章为安全社公众号的Poker安全所发,本文仅为学习复现。 二、介绍 指纹混淆技术,顾名思义,就是迷惑指纹扫描识别技术。 三、思路 作者的思路: 1、伪…

代码随香录day31

今天开始贪心算法了! 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 贪心算法一般分为如下四步: 将问题分解为若干个子问题找出适合的贪心策略求解每一个子问题的最优解将局部最优解堆叠成全局最优解 455. 分发饼干 这里的思路…

openEuler?搭建java开发环境的详细过程

目录 1. 初始化环境2. 安装jdk83. 安装SVN4. 安装Git5. 安装Node.js6. 下载并激活IntelliJ IDEA7. 下载并激活Navicat 本文操作系统及版本号:↓ openEuler release 22.03 LTS Linux version 5.10.0-60.35.0.64.oe2203.x86 _64 1. 初始化环境 ? 1 2 3 4 # 1. 更新…

Spring事务的传播机制与隔离级别

目录 前言事务的隔离级别事务特性Spring 中设置事务隔离级别MySQL的隔离级别Spring中的隔离级别 Spring的传播机制事务传播机制是什么?为什么需要事务传播机制?事务传播机制有哪些? 事务的隔离级别 与 传播机制 解决的问题 前言 无论对于那个…

2020年全国硕士研究生入学统一考试管理类专业学位联考写作试题——解析版

四、写作第56~57小题,共65分。其中论证有效性分析30分,论说文35分。 56. 论证有效性分析:分析下述论证中存在的缺陷和漏洞,选择若干要点,写一篇600字左右的文章,对该论证的有效性进行分析和评论。( 论证有…

自动装配再次理解

随便点进去一个自动装配类,也就是spring.factories 文件下的一个全限定名指定的一个配置类 里面有个内部类 Encoding 类 这个注解是绑定了yaml文件,通过前缀可以往里面赋值,来实现自定义配置Springboot 了解完自动装配的原理后,我…

<C语言> 预处理和宏

1.预定义符号 __FILE__ //进行编译的源文件 __LINE__ //文件当前的行号 __DATE__ //文件被编译的日期 __TIME__ //文件被编译的时间 __STDC__ //如果编译器遵循ANSI C,其值为1,否则未定义这些预定义符号都是C语言内置的。 举个例子&…

如何高效维护电脑

电脑维护技巧:让你的电脑始终高效稳定 电脑维护技巧:让你的电脑始终高效稳定引言方向一:介绍你的电脑方向二:介绍一下你的日常维护措施方向三:给出一些你觉得有用的维护技巧方向四:其他你想补充的方向五&am…