redis 入门指南-基础命令

基础命令

获得符合规则的键名列表

KEYS pattern
pattern 可使用 glob 通配符格式,glob风格通配符规则

符号含义
?匹配一个字符
*匹配0个或者任意个字符
[ ]匹配括号间的任一字符,用 “-” 符号表示范围 a[b-d],匹配到ab,ac,ad
\转义符,对元字符转义

一、Redis数据类型

字符串(string)
它是二进制安全的,能存储任何形式的字符串,包括二进制数据,序列化的数据,JSON化的对象,甚至是一张经过Base64编码后的图片。字符串类型的最大能存储512MB的数据。

散列(hash)
Redis是采用字典结构以键值对的形式存储数据的,散列类型也是一种字典结构,采用了域(field)值(value)的映射表,但值只能是字符串,不支持其它数据结构。一个散列类型最多可以包含2^32-1个键值对,也就是40多亿个数据。

列表(list)
列表类型可以存储一个有序的字符串列表,常用的操作就是向列表两端添加元素。列表类型内部使用双向链表(double linked list)实现的,所以向列表两端添加元素的时间复杂度为O(1),越接近两端的元素速度就越快。不过使用列表的的代价是通过索引访问元素较慢,例如访问第999个元素,列表需要一个一个的数过去找到第999个元素才能返回。但是访问两端的话,无论你的数据是1000条取前10条,还是1000万条取前10条,它的速度是一样快的,因为只取前10,和列表有多少条数据是没有任何关系的。

集合(set)
在集合中每个元素都是不同的,且没有顺序,一个集合最多可以存储2^32-1个字符串,集合类型在Redis内部是使用值为空的散列表(hash table)实现的,所以这些操作的时间复杂度都是O(1)。最方便的是多个集合类型键之间还可以进行并集、交集和差集运算。

有序集合(sorted set)
从名字可以知道,它与集合的区别就是“有序”二字,在集合的基础上为每个元素都关联了一个分数,这使得我们不仅可以完成插入、删除和判断元素是否存在等操作,还能获得分数最高或者最低的前N个元素,有序集合使用散列表和跳跃表实现的,所以即使读位于中间部分的数据也很快(时间复杂度O(log(N))),有序集合最多可以包含2^32-1个元素

入门

创建一名为bar 的键:
SET bar 1

获得所有键, 使用 KEYS * 会遍历 redis 中所有的键,但键太多时会影响性能
KEYS *
KEYS title*

判断一个键是否存在 @return 0 1
EXISTS bar
EXISTS noexists

删除键,可以删除一个或多个键,返回值是删除的键的个数。
DEL bar
DEL bar foo key

获得键值的数据类型 TYPE key
TYPE foo
TYPE bar

字符串类型 命令

赋值 (SET)  SET key value
SET nickname Tony

取值 (GET )GET key
GET nickname

同时设置多个键值(MSET)MSET key value [ key value ...]
MSET key1 v1 key2 v2 key3 v3

同时获得多个键值(MGET)MGET key [ key ...]
MGET key3 key1

当键不存在时才设置键值对(SETNX)SETNX key value,set if not exists的缩写,当key不存在则设置value,存在则什么也不做
SETNX college '计算机学院'

当键不存在时才设置键值对 设置多个(MSETNX) MSETNX key value [key value ...],MSETNX命令具有原子性,所有键都不存在才能设置成功,有一个键存在就会全部失败
MSETNX key1 '张三' sex 1 age 10

获取键的子字符串值(GETRANGE)GETRANGE key start end ,字符串截取
GETRANGE key 0 4  #'zhangsan' 会截取 'zhang' 

设置键的偏移量(SETBIT)SETBIT offset vlaue
SETBIT key 6 1

获取键的偏移量(GETBIT)GETBIT offset
GETBIT key 6

递增数字(INCR)INCR key,当key不存在会初始化键值为0再执行INCR
INCR num

增加指定的整数(INCRBY)INCRBY key increment
INCRBY bar 10

增加指定浮点数(INCRBYFLOAT)INCRBYFLOAT key increment
INCRBYFLOAT bar 2.7
INCRBYFLOAT bar 5E+4

递减整数(DECR)DECR key
DECR num

减少指定的整数(DECRBY)DECRBY key decrment,只能操作 INT 型或者全由数字组成的STRING,设置过INCRBYFLOAT的键值也会操作失败。
DECRBY num 5

向尾部加值(APPEND)key value, 键存在就追加至尾部,不存在就设置为 value
APPEND key " world!"

为键设置生存时间 秒(SETEX)SETEX key seconds value,操作SETEX命令必须同时设置时间(seconds)和值(value)
SETEX key1 100 'abc'#设置key1生存时间100秒

为键设置生存时间 毫秒(PSETEX)PSETEX key milliseconds value
PSETEX user 1000 '张三' #设置user生存时间1000毫秒

查看生存时间 秒(TTL)TTL key1,返回剩余生存时间,-1永久有效,-2键不存在
TTL key1 
查看生存时间 毫秒(PTTL)PTTL key1
PTTL key1

获取字符串长度(STRLEN)STRLEN key ( utf-8编码的汉字长度是3个字符)
STRLEN key1

散列类型 HASH

散列类型命令多数以 H 开头

赋值(HSET)HSET key field vlaue
HSET car price 500
HSET car name M100

取值(HGET)HGET key field
HGET car name
HGET car price

赋值多键值到哈希表中 (HMSET)HMSET key field1 value field2 vlaue
HMSET car price 100 model p10

获取多个键的符  (HMGET )HMGET key field1 field2
HMGET car price model

获取哈希表中的所有键(HKEYS)HKEYS key
HKEYS car

获取哈希表中的所有值(HVALS)VALS key
HVALS  car

获取哈希表中所有的键值(HGETALL)HGETALL key,返回关联数组
HMGETALL car

为哈希表不存在的域设值(HSETNX)HSETNX key field value,字段不存在才赋值,存在则不执行任何操作
SETNX user login_status 1

为哈希表的值加上增量值(HINCRBY)HINCRBY key field increment,键不存在时自动创建并初始化值为0,再执行HINCRBY命令
HINCRBY user age 1
HINCRBY user weight -5

为哈希表的值加上浮点数增量值(HINCRBYFLOAT)HINCRBYFLOATkey field increment
HINCRBY user weight 10.9
HINCRBY user weight -2.5

判断字段是否存在(HEXISTS)HEXISTS key field
HEXISTS car price

删除字段(HDEL) HDEL key field [ filed ...],可以删除一个或多个字段,返回值是删除成功的个数
HDEL car price

统计哈希表中键的数量(HLEN)HLEN key
HLEN key

统计哈希表的值的字符串长度(HSTRLEN)HSTRLEN key field
HSTRLEN car name

实践:
使用多个字符串存储一个对象,与使用一个散列类型储存一个对象对比 :

键值-字段字段值
post:42:title第一篇日志title第一篇日志
post:42:author小白post: 42author小白
post:42:time7月1日time7月1日
post:42:content今天星期一content星期一

列表类型

向列表左边增加一个或多个元素(LPUSH)LPUSH key value [ value ...],返回值是列表长度
LPUSH numbers 3 2 1 

向列表尾部增加一个或多个元素(RPUSH)RPUSH key value [ value ...]
RPUSH numbers 100 200 300

插入一个值到列表中某个值的前面或后面(LINSERT)LINSERT key BEFORE | AFTER pivot value,有多个pivot值时会找左边第一个pivot
LPUSH key1 99 88 66 #66 88 99
LINSERT key1 AFTER 66 70 #66 70 88 99

修改列表元素值(LSET)LSET key index value
LSET key1 0 55

获得指定索引的元素值(LINDEX)LINDEX key index
LINDEX key1 0

获取列表指定片段内的元素(LRANGE)LRANGE key start end ,支持负数-1即最后一个,-1即倒数第二个
LRANGE numbers -2 -1
LRANGE numbers 0 -1

从列表头部弹出元素(LPOP)LPOP key,返回头元素 并删除这个头元素
LPOP key1 

从列表尾部弹出元素(RPOP)RPOP key,返回尾元素 并删除这个元素
RPOP key1 

获取列表长度(LLEN)LLEN key
LLEN key1

获取并移出列表的头元素(BLPOP)BLPOP key [key ...] timeout
它是 LPOP key 命令的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待超时或发现可弹出元素为止,返回阻塞的时间
BLPOP newkey 10 # 等待10秒后删除列表newkey的头元素

获取并移出列表的尾元素(BRPOP)BRPOP key [key ...] timeout
BRPOP key1 10 # key1是空列表时阻塞10秒,10秒内有元素后立刻删除列表Key1的尾元素,10秒超时返回(nil)

删除列表中指定个数的元素(LREM)LREM key count value
LREM number 0 -1 #count等于0,删除所有与-1相等的元素,删除所有-1
LREM numbers -10 2 #count小于0,从列表尾部删除count个元素,删除10个2 
LREM number 6 5 #count大于0,从列表头部删除count个元素,删除6个5

在指定区间修剪列表(LTRIM)LTRIM key start stop
LTRIM key1 0 2 #只保留列表key1的前3个元素,其它删除。

将列表元素移动到另一列表中(RPOPLPUSH)RPOPLPUSH source destination,从名字可看出功能,先执行RPOP,再执行LPUSH
RPOPLPUSH key1 key2 #将列表key1的尾元素移到key2的头部
RPOPLPUSH key1 key1 #对key1 执行rpop再执行lpush
使用RPOPLPUSH可以循环读取列表中的值,当有新元素添加进来时,这个循环也能正常工作

在指定时间内移动列表元素到另一列表中(BRPOPLPUSH)BRPOPLPUSH source destination timeout
BRPOPLPUSH key1 key2 30

实践:利用redis做一个消息队列,把数据通过队列的方式存储在硬盘上
伪代码示例,1把用户ID加入列表,2从列表弹出一个元素,3把元素写入本地硬盘,4成功返回成功状态,失败的话元素重新加到列表中。

LPUSH number 1 2 3 4 5 5 7 9 0 99 8 6 5 55 77 88
$num = LPOP number
$state = file_put_content('log.txt', $num, FILE_APPEND);
if($state){
	echo '写入成功';
}else{
	LPUSH number $num
	echo "写入失败"
}

集合类型

集合SET,多数命令以S开头
在一个视频中,为每个视频存储视频标签,可利用集合的特性,即每个元素都是唯一,且没有顺序。

集合与列表类型对比
集合是无序且唯一的,列表是有序但不是唯一的,存储内容都是2^32-1个字符
集合内部是使用值为空的散列表实现的,且不存在重复数据,所以操作的时间复杂度是O(1)

向集合中增加一个或者多个元素(SADD)SADD key member [ member ...]
SADD city 'gz' 'sz' 'cq' 'dg' 

判断某个元素是否在集合中(SISMEMBER)SISMEMBER key number
SISMEMBER city 'gz'

获取集合中元素的数量(SCARD)SCARD key
SCARD city

获取集合中的所有元素(SMEMBERS)SMEMBERS key
SMEMBERS city

随机获取集合中的一个或多个元素(SRANDMEMBER)SRANDMEMBER key [count]
SRANDMEMBER city 8

移动集合元素到另一个集合中(SMOVE)SMOVE source destination member
SMOVE city2 city 'cq' //将元素cq从集合city2移到集合city

随机删除集合中的单个或多个元素(SPOP)SPOP key [count]
SPOP city 5

删除集合中的多个指定元素(SREM)SREM key member [ member ...]
SREM city gz sz dg

集合间运算
获取多个集合元素的差集(SDIFF)SDIFF key [key ...]
SDIFF city city2 city3

获取多个集合差集的元素个数(SDIFFSTORE)SDIFFSTORE key [key ...]
SDIFF city city2 city3

获取多个集合元素的交集(SINTER SINTER key [key ...]
SINTER city city2

获取多个集合的元素个数(SINTERSTORE)SINTERSTORE key [key ...]
SINTERSTORE city3 city city2

获取多个集合元素的并集(SUNION)SUNION key [key ...]
 SUNION city city2 

有序集合 (sorted set)

有序集合与列表相同点,二者都是有序的,二者都可以获得某一范围的元素。
区别和应用场景:
一、列表通常链表实现的,获取靠近两端的数据速度极快,但中间的数据会较慢,适合新闻事、日志这类访问两端的场景
二、有序集合使用散列表和跳跃表(skip list)实现的,所以读取中间部分速度也快(时间复杂度O(log(N)))
三、列表不能简单调整某个元素位置,有序集合可以(通过更改元素的分数)
四、有序集合比列表类型耗内存

增加元素 ZADD ZADD key score member [score member ...]
ZADD scores 89 ‘jack’ 67 'tony' 100 'tom'

获取某个元素分数
ZSCORE scores 'jack'

为分数值加上增量 ZINCRBY key increment member
ZINCRBY scores -10 'jack'

获取元素个数 ZCARD ZCARD key
ZCARD scores

获取在指定区间内的元素数量 ZLEXCOUNT ZLEXCOUNT key min max
ZLEXCOUNT scores - +

获取在指定范围内的元素-升序 ZRANGE ZRANGE key start stop [WITHSCORES]
ZRANGE scores 0 -1

获取在指定范围内的元素-降序 ZREVRANGE ZREVRANGE key start stop [WITHSCORES]
ZREVRANGE scores 0 -1

获取元素的分数值 ZSCORE ZSCORE key member
ZSCORE scores 'tom'

获取集合在指定范围内的元素 ZRANGEBYLEX ZRANGEBYLEX key min max [LIMIT offset count]
ZRANGEBYLEX scores - + //加减表示负无穷、正无穷

获取指定分数内的元素 ZRANGEBYSCORE ZRANGEBYSCORE key min max [WITHSCRES] [LIMIT offset count]
ZRANGEBYSCORE scores 80 100 WITHSCORES

获取指定区间内的所有元素 ZREVRANGEBYSCORE ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
ZREVRANGEBYSCORE scores 0 -1 WITHSCORES

获得某个元素排名ZRANK ZRANK key member
ZRANK scores 0 -1

获取有序集合元素的倒序排名 ZREVRANK ZREVRANK key member
ZREVRANGE scores 0 -1

有序集合运算
保存多个有序集合的交集 ZINTERSTORE ZINTERSTORE destination numkeys key [key ...]
ZINTERSTORE scores 2 scores9 scores5

保存多个有序集合的并集 ZUNIONSTORE ZUNIONSTORE destination numkeys key [key ...]
ZUNIONSTORE  scores 2 scores9 scores5

删除有序集合中的一个或多个元素 ZREM key member [member ...]
ZREM scores 'jack' 'tom'

删除有序集合在指定区间的元素 ZREMRANGEBYLEX ZREMRANGEBYLEX key min max
ZREMRANGEBYLEX score 0 2

按照排名范围删除元素 ZREMRANGEBYRANK ZREMRANGBYRANK key start stop
ZREMRANGBYRANK scores 0 3

按照分数范围删除元素 ZREMRANGEBYSCORE ZREMRANGEBYSCORE key min max
ZREMRANGEBYSCORE scores 80 100

获得指定分类范围内的元素个数 ZCOUNT ZCOUNT key min max
ZCOUNT scoreboard 90 100

二、Redis应用场景

生存时间

在开发中会经常遇到一些有时效的数据,如限时优惠、缓存、登录验证码等,需要过期就删除这些数据。

EXPIRE设置
使用expire命令设置一个键的生存时间,到时间后redis就会自动删除它。
EXPIRE设置字符串 session:29e34键在10分钟后被删除

SET session:29e34 uid314
expire session:29e34 600

除了能设置字符串类型,EXPIRE 也能设置哈希、列表、集合、有序集合的的生存时间。
输出:
OK, (integer) 1

TTL查询

TTL查询一个键还有多久会被删除,当键不存在时返回 -2,当键永久存在会返回-1

SET foo bar
EXPIRE foo 60
TTL foo
TTL foo
SET persist abc
TTL persist

输出: OK, (integer) 1 , 56, -1。 OK, (integer) -1

PERSIST取消
PERSIST命令取消设置的生存时间,或者为键set设置新值

SET foo abc
EXPIRE foo 200
PERSIST foo
TTL foo
SET foo bar

输出: OK , (integer) 1 , (integer) 1 , -1, OK

实例操作
一、访问限制
每分钟最多访问10次,操作流程的伪代码实现

$listLength = LLEN rate.limiting:$IP
if $lstLength <10
	LPUSH rate.limiting:$IP now()
else
	$time = LINDEX rate.limiting:$IP, -1
	if now() - $time < 60
		print 访问频繁,请稍后再试
	else
	LPUSH rate.limiting:$IP , now()
	LTRIM rate.limiting:$IP ,0 ,9

二、实现缓存
将一些访问频繁但对CPU或IO资源消耗高的计算结果缓存起来,并到期释放,以提高网站的负载能。
伪代码实现

$rank = GET cache:rank
if not $rank
	$rank = 计算排名 ..
	MUITI
	SET cache:rank , $rank
	EXPIRE cache:rank, 7200
	EXEC

配置内存
当内存有限时,大量使用缓存会导致Redis占满内存,而时长设置太短也会导致redis命中率过低使内存白白地闲置
修改配置文件的maxmemory参数,限制redis最大可用内存大小,当超出限制时,依据maxmemory-policy参数指定策略来删除不要的键

规则说明
volatile-lru使用LRU算法删除一个键,(只删除设置了生存时间的键)
allkeys-lru使用LRU算法删除一个键
volatile-random随机删除一个键盘(只删除设置了生存时间的键)
allkeys-random随机删除一个键
volatile-ttl删除生存时间最近的一个键
noeviction不删除键,只返回错误

事务

Redis中的事务是一组命令的集合,事务同命令一样都是Redis的最小执行单位,一个事务的命令要么都执行,要么不执行。
MULTI 事务开始
EXEC 事务执行
MULIT 开始事务,SADD添加数据,返回QUEUED,进入等待执行的事务队列。最后使用EXEC执行所有命令。如果发送EXEC命令前客户端断线了,则Redis会清空事务队列,事务中的命令都不会再执行。

MULIT
SADD "user:1:following" 2
SADD "user:1:following" 2
EXEC

输出: OK, QUEUED, QUEUED, (integer) 1 (integer) 2

Redis 的执行顺序时,当执行过程中出现命令语法错误,执行EXEC后直接返回错误,不会再执行任何命令
Redis事务库没有提供回滚(rollback)功能,出现数据类型错误在执行前是检测不出来的,例如第一个命令执行成功,第二个命令执行时出现数据类型错误那么会写入失败,第三个命令成功,执行结果就是一三成功二失败,对此开发者必须自己收拾出错后的摊子

WATCH命令
监控要执行事务的键,从redis中读取一条键值后,防止此键值被其他客户端改动,可使用watch命令监控一个或多个键,一旦其中一个键值出现改过,事务就不会执行。
事务成功执行后,会取消WATCH对键的监控,也可使用UNWATCH命令取消监控。
执行watch命令之后,事务执行前key的值被更改了,事务失败。

set key 1
watch key 
set key 2 
multi 
set key 3
exec
get key

输出:“2”

排序

SORT命令
加 DESC 参数实现倒序排序,加LIMIT参数返回指定数量
sort tag: ruby:posts DESC LIMIT 0 2

有序集合

ZADD myzset a 2 b 3 c 1 d5
SORT myzset

输出: (integer) 4, 1 2 3 5

列表类型

LPUSH mylist 4 2 6 1 3 7 
SORT mylist
SORT mylist desc
SORT mylist desc limit 0 2

输出: (integer) 6 , 1 2 3 4 6 7 , 1 2 3 4 6 7, 7 6

对字典排序,需要加ALPHA参数

LPUSH mylist a c e d B C A
SORT mylist
SORT mylist ALPHA

输出: (integer) 7, (error)…, A B C a c d e

BY参数
对指定字段排序
BY参数的语法为"BY参考键",(键名->字段名),
下面的例子中,SORT命令会读取post:2、6、12、26这几个散列键中的time字段的值,并以此决定 tag:ruby:posts键中各个文章ID的顺序。
参考键可以是散列类型,也可以是字符串类型

SORT tag:ruby:posts BY post:*->time DESC
SORT sortbylist BY itemscore:* DESC

GET参数
SORT命令的GET参数,它的作用是使返回值不再是元素自身的值,而是GET参数指定的键值,就像PHP函数array_column()函数一样。
GET参数不会影响排序,一个SORT命令可以有多个GET参数,返回ID使用GET #

SORT tag:ruby:posts BY post:*->time DESC GET post:*->title
SORT tag:ruby:posts BY post:*->time DESC GET post:*-title GET post:*->time

STORE参数
如果希望保存排序结果,使用STORE参数
把结果保存到sort.result键中

SORT tag:ruby:posts BY post:*->time DESC GET post:*->title GET # STORE sort.result

性能优化
SORT是Redis中最强大最复杂的命令之一,时间复杂度是O(n+mlogm),其中n表示元素个数,m表示要返回的元素个数。当n较大时SORT命令的性能相对较低,Redis在排序前会建立一个长度为n的容器来存储待排序的元素,虽是临时 过程,但操作大量数据排序时会严重影响性能。
SORT命令注意点:
尽可能减少待排序元素的数量( n尽可能小)
LIMIT参数只获取需要的数据(m尽可能小)
数据量大时使用STORE参数缓存排序结果

。。。

三、实践篇

PHP与Redis

Reids官方推荐客户端是Predis和phpredis,前者是完全php代码实现的原生客户端,而后者是C语言编写的PHP扩展。在功能上并无差别,在性能上后者更好一点,但是除非有大量命令操作,否则很难区分两者的性能。

安装redis,启动redis

使用时首先要引入 autoload.php文件

require './predis/autoload.php'

创建Redis的连接

$redis = new Predis\Client();

如需要更改地址或接口,可以使用

$redis = new Predis\Client([
	'scheme'	=> 'tcp',
	'host'	=> '127.0.0.1',
	'port'	=> 6379,	
])

测试:

$redis->set('foo', 100);
echo $redis->get('foo');
$redis->lpush('number', 1,3,6,2);
print_r($redis->lrange('number',0,-1));

输出:
100
Array ( [0] => 2 [1] => 6 [2] => 3 [3] => 1 )

简便用法
Predis为许多命令额外提供了简便用法
MGET/MSET

$user = [
	'user:1name' => 'Tom',
	'user:2name' => 'Jack',
];
$redis->mset($user);
print_r($redis->mget(['user:1:name', 'user:2:name']));

相当于命令

$redis->mset('user:1:name', 'Tome', 'user:2:name', 'Jack');

输出:
Array ( [0] => Tom [1] => Jack )

HMSET/HMGET/HGETALL
在Predis中调用HMSET的方式与MSET类似
更方便的命令是HGETALL,Predis会将Redis返回的结果组装成关联数组返回

$user = [
	'name' => 'Tom',
	'age' => '20',
];
$redis->hmset('user:1',$user);

print_r($redis->hmget('user:1','name','age'));
print_r($redis->hgetall('user:1'));

相当于命令

$redis->hmset('user:1','name', 'Tome', 'age', '20');

输出:
Array ( [0] => Tome [1] => 20 )
Array ( [name] => Tome [age] => 20 )

LPUSH/SADD/ZADD
LPUSH和SADD的调用方式类似

$item = ['a', 'b'];
$redis->lpush('list', $item);

print_r($redis->lrange('list', 0,-1));

相当于命令

$redis->lpush('list', 'a', 'b')

输出:
Array ( [0] => b [1] => a )

ZADD调用方式

$items = ['Han' => '100', 'Jan' => '0'];
$redis->zadd('zset', $items);

// 相当于
$redis->zadd('zset', '100', 'Han', '0', 'Jan');

SORT
Predis中调用SORT命令的方式和其他命令不同,必须将SORT命令中除键名外的参数作为关联数组传入到函数中,

SORT mylist BY weight_* LIMIT 0 10 GET value_* GET # ASC Alpha STORE result

对于上面的命令,Predis的调用方法需要这样写

$redis->sort('mylist',[
	'by'	=> 'weight_*',
	'limit'	=> [0, 10],
	'get'	=> ['value_*', '#'],
	'sort'	=> 'asc',
	'alpha'	=> true,
	'store'	=> 'result',
]);

用户注册登录功能

本节为演示Redis功能,并没有对用户提交的数据做验证,在实际项目中一定要做验证。永远不要相信用户提交的任何数据。
检查邮箱是否注册过了

header('Content-type:text/html; charset=utf-8');

//用户提交的基本资料
$mail = 'ab@qq.com';
$nickname = 'Jack';
$pwd = '123456';

$redis = new Predis\Client();
if($redis->hexists('email.to.id', $mail)){
	echo "邮箱已被注册了";die;
}else{
	echo "邮箱可以注册";
}

存储用户资料

//获取一个自增的用户ID
$userID = $redis->incr('user.count');

$hash_pwd = password_hash($pwd , PASSWORD_DEFAULT);
//存储用户信息
$redis->hmset('user:{$userID}', [
	'email'	=> $mail,
	'pwd'	=> $hash_pwd,
	'name'	=> $nickname,
]);
$redis->hset('email.to.id', $mail, $userID);
echo '注册成功';

登录

// 获取用户ID
$userID = $redis->hget('email.to.id', $mail);

// 获取用户密码哈希值
$password = $redis->hmget('user:{$userID}', 'pwd'); 

//检验密码是否匹配
if (password_verify($pwd, $password[0]) === false){	
	echo '用户名或密码错误!';
}else{
	echo '登录成功!';
}

输出:登录成功

四、Redis管理工具

一、命令行工具
redis-cli
安装redis,打开windows命令行切换到redis的安装目录,用命令redis-server启动服务,再打开一个窗口,执行命令redis-cli,即可操作redis数据库了。

redis-server
redis-cli
set key1 100
get key1

二可视化管理工具 PHPRedisAdmin
可以在github下载,配置好域名就可以使用了

git clone https://github.com/ErikDubbelboer/phpRedisAdmin.git
cd phpRedisAdmin
git clone https://github.com/nrk/predis.git vendor

参考资料
《Redis入门指南》
《从零开始学Redis》

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值