phpredis中文手册——《redis中文手册》 php版

来源:http://www.prospettivedarte.com 作者:计算机教程 人气:77 发布时间:2019-07-06
摘要:phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系 redis中文手册: http://readthedocs.org/docs/redis/en/latest/   本文是参考《redis中文手册》,将示例代

phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系

redis中文手册:http://readthedocs.org/docs/redis/en/latest/ 

本文是参考《redis中文手册》,将示例代码用php来实现,注意php-redis与redis_cli的区别(主要是返回值类型和参数用法)。

目录(使用CTRL F快速查找命令):

Key String Hash List Set
  • 键(Key)
    • DEL
    • KEYS
    • RANDOMKEY
    • TTL
    • EXISTS
    • MOVE
    • RENAME
    • RENAMENX
    • TYPE
    • EXPIRE
    • EXPIREAT
    • OBJECT
    • PERSIST
    • SORT
  • 字符串(String)
    • SET
    • SETNX
    • SETEX
    • SETRANGE
    • MSET
    • MSETNX
    • APPEND
    • GET
    • MGET
    • GETRANGE
    • GETSET
    • STRLEN
    • INCR
    • INCRBY
    • DECR
    • DECRBY
    • SETBIT
    • GETBIT
  • 哈希表(Hash)
    • HSET
    • HSETNX
    • HMSET
    • HGET
    • HMGET
    • HGETALL
    • HDEL
    • HLEN
    • HEXISTS
    • HINCRBY
    • HKEYS
    • HVALS
  • 表(List)
    • LPUSH
    • LPUSHX
    • RPUSH
    • RPUSHX
    • LPOP
    • RPOP
    • BLPOP
    • BRPOP
    • LLEN
    • LRANGE
    • LREM
    • LSET
    • LTRIM
    • LINDEX
    • LINSERT
    • RPOPLPUSH
    • BRPOPLPUSH
  • 集合(Set)
    • SADD
    • SREM
    • SMEMBERS
    • SISMEMBER
    • SCARD
    • SMOVE
    • SPOP
    • SRANDMEMBER
    • SINTER
    • SINTERSTORE
    • SUNION
    • SUNIONSTORE
    • SDIFF
    • SDIFFSTORE

 

Sorted Set Pub/Sub Transaction Connection Server
  • 有序集(Sorted Set)
    • ZADD
    • ZREM
    • ZCARD
    • ZCOUNT
    • ZSCORE
    • ZINCRBY
    • ZRANGE
    • ZREVRANGE
    • ZRANGEBYSCORE
    • ZREVRANGEBYSCORE
    • ZRANK
    • ZREVRANK
    • ZREMRANGEBYRANK
    • ZREMRANGEBYSCORE
    • ZINTERSTORE
    • ZUNIONSTORE
  • 发布/订阅(Pub/Sub)
    • PUBLISH
    • SUBSCRIBE
    • PSUBSCRIBE
    • UNSUBSCRIBE
    • PUNSUBSCRIBE
  • 事务(Transaction)
    • WATCH
    • UNWATCH
    • MULTI
    • EXEC
    • DISCARD
  • 连接(Connection)
    • AUTH
    • PING
    • SELECT
    • ECHO
    • QUIT
  • 服务器(Server)
    • BGREWRITEAOF
    • BGSAVE
    • SAVE
    • LASTSAVE
    • DBSIZE
    • SLAVEOF
    • FLUSHALL
    • FLUSHDB
    • SHUTDOWN
    • SLOWLOG
    • INFO
    • CONFIG GET
    • CONFIG SET
    • CONFIG RESETSTAT
    • DEBUG OBJECT
    • DEBUG SEGFAULT
    • MONITOR
    • SYNC

phpredis是redis的php的一个扩展,效率是相当高有链表排序功能,对创建内存级的模块业务关系

很有用;以下是redis官方提供的命令使用技巧:

下载地址如下:

https://github.com/owlient/phpredis(支持redis 2.0.4)

Redis::__construct构造函数
$redis = new Redis();

connect, open 链接redis服务
参数
host: string,服务地址
port: int,端口号
timeout: float,链接时长 (可选, 默认为 0 ,不限链接时间)
注: 在redis.conf中也有时间,默认为300

pconnect, popen 不会主动关闭的链接
参考上面

setOption 设置redis模式

getOption 查看redis设置的模式

ping 查看连接状态

 

KEY相关操作

DEL

移除给定的一个或多个key

如果key不存在,则忽略该命令。

时间复杂度:
O(N),N为要移除的key的数量。

移除单个字符串类型的key,时间复杂度为O(1)。

移除单个列表、集合、有序集合或哈希表类型的key,时间复杂度为O(M),M为以上数据结构内的元素数量。

返回值:
被移除key的数量。

 

//DEL
# 情况1: 删除单个key
$redis->set('myname','ikodota');
echo $redis->get('myname').'<br>'; # 返回:ikodota

$redis->del('myname');# 返回 TRUE(1)
var_dump($redis->get('myname')); # 返回 bool(false)

# 情况2: 删除一个不存在的key
if(!$redis->exists('fake_key')) # 不存在
var_dump($redis->del('fake_key')); # 返回 int(0)

# 情况3: 同时删除多个key
$array_mset=array('first_key'=>'first_val',
          'second_key'=>'second_val',
          'third_key'=>'third_val');
$redis->mset($array_mset); #用MSET一次储存多个值
$array_mget=array('first_key','second_key','third_key');
var_dump($redis->mget($array_mget)); #一次返回多个值 //array(3) { [0]=> string(9) "first_val" [1]=> string(10) "second_val" [2]=> string(9) "third_val" }

$redis->del($array_mget); #同时删除多个key
var_dump($redis->mget($array_mget)); #返回 array(3) { [0]=> bool(false) [1]=> bool(false) [2]=> bool(false) }

KEYS

KEYS pattern

`查找符合给定模式的key`。

KEYS *命中数据库中所有key

KEYS h?llo命中hello, hallo and hxllo等。

KEYS h*llo命中hlloheeeeello等。

KEYS h[ae]llo命中hellohallo,但不命中hillo

特殊符号用""隔开

时间复杂度:
O(N),N为数据库中key的数量。

返回值:
符合给定模式的key列表。

警告 :KEYS的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(Set)

 

//KEYS
#$redis->FLUSHALL();
$array_mset_keys=array('one'=>'1',
          'two'=>'2',
          'three '=>'3',
          'four'=>'4');
$redis->mset($array_mset_keys); #用MSET一次储存多个值
var_dump($redis->keys('*o*')); //array(3) { [0]=> string(4) "four" [1]=> string(3) "two" [2]=> string(3) "one" }
var_dump($redis->keys('t??')); //array(1) { [0]=> string(3) "two" }
var_dump($redis->keys('t[w]*')); //array(1) { [0]=> string(3) "two" }
print_r($redis->keys('*')); //Array ( [0] => four [1] => three [2] => two [3] => one )

RANDOMKEY

从当前数据库中随机返回(不删除)一个key

时间复杂度:
O(1)

返回值:
当数据库不为空时,返回一个key

当数据库为空时,返回nil。

 

//RANDOMKEY
$redis->FLUSHALL();
# 情况1:数据库不为空
$array_mset_randomkey=array('fruit'=>'apple',
                'drink'=>'beer',
                'food'=>'cookis');
$redis->mset($array_mset_randomkey);
echo $redis->randomkey(); 
print_r($redis->keys('*')); # 查看数据库内所有key,证明RANDOMKEY并不删除key//Array ( [0] => food [1] => drink [2] => fruit )

# 情况2:数据库为空
$redis->flushdb();  # 删除当前数据库所有key
var_dump($redis-> randomkey()); //bool(false)

 

TTLTTL key

返回给定key的剩余生存时间(time to live)(以秒为单位)。

时间复杂度:
O(1)

返回值:
key的剩余生存时间(以秒为单位)。

key不存在或没有设置生存时间时,返回-1 。

 

//TTL
# 情况1:带TTL的key
$redis->flushdb();
//$redis->set('name','ikodota'); # 设置一个key
$redis->expire('name',30);  # 设置生存时间为30秒 //return (integer) 1
echo $redis->get('name'); //return ikodota
echo $redis->ttl('name'); //(integer) 25

//echo $redis->ttl('name');  # 30秒过去,name过期 //(integer) -1
var_dump($redis->get('name')); # 过期的key将被删除 //return bool(false);

# 情况2:不带TTL的key
$redis->set('site','wikipedia.org');//OK
var_dump($redis->ttl('site'));//int(-1)

# 情况3:不存在的key
$redis->EXISTS('not_exists_key');//int(0)
var_dump($redis->TTL('not_exists_key'));//int(-1)

EXISTS

EXISTS key

检查给定key是否存在。

时间复杂度:
O(1)

返回值:
key存在,返回1,否则返回0

//EXISTS
echo '<br>EXISTS<br>';
$redis->set('db',"redis"); //bool(true) 
var_dump($redis->exists('db'));  # key存在 //bool(true) 
$redis->del('db');   # 删除key //int(1)
var_dump($redis->exists('db'))  # key不存在 //bool(false)

MOVE
MOVE key db

将当前数据库(默认为0)的key移动到给定的数据库db当中。

如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key,或者key不存在于当前数据库,那么MOVE没有任何效果。

因此,也可以利用这一特性,将MOVE当作锁(locking)原语。

时间复杂度:
O(1)

返回值:
移动成功返回1,失败则返回0

//MOVE
echo '<br><br>MOVE<br>';
# 情况1: key存在于当前数据库
$redis->SELECT(0);  # redis默认使用数据库0,为了清晰起见,这里再显式指定一次。//OK
$redis->SET('song',"secret base - Zone"); //OK
var_dump ($redis->MOVE('song',1));  # 将song移动到数据库1 //bool(true)

# 情况2:当key不存在的时候
$redis->SELECT(1);
var_dump ($redis->EXISTS('fake_key'));//bool(false);
var_dump($redis->MOVE('fake_key', 0));  # 试图从数据库1移动一个不存在的key到数据库0,失败) //bool(false)

$redis->SELECT(0); # 使用数据库0
var_dump($redis->EXISTS('fake_key'));  # 证实fake_key不存在 //bool(false)

# 情况3:当源数据库和目标数据库有相同的key时

$redis->SELECT(0);  # 使用数据库0
$redis->SET('favorite_fruit',"banana");

$redis->SELECT(1);  # 使用数据库1
$redis->SET('favorite_fruit',"apple");

$redis->SELECT(0);  # 使用数据库0,并试图将favorite_fruit移动到数据库1
var_dump($redis->MOVE('favorite_fruit',1));  # 因为两个数据库有相同的key,MOVE失败 //return bool(false)
echo $redis->GET('favorite_fruit');  # 数据库0的favorite_fruit没变 //return banana

$redis->SELECT(1);
echo $redis->GET('favorite_fruit');   # 数据库1的favorite_fruit也是 //return apple

RENAME 

RENAME key newkey

key改名为newkey

keynewkey相同或者key不存在时,返回一个错误。

newkey已经存在时,RENAME命令将覆盖旧值。

时间复杂度:
O(1)

返回值:
改名成功时提示OK,失败时候返回一个错误。

//RENAME
echo '<br><br>RENAME<br>';
# 情况1:key存在且newkey不存在
$redis->SET('message',"hello world");
var_dump($redis->RENAME('message','greeting'));  //bool(true)
var_dump($redis->EXISTS('message'));  # message不复存在 //bool(false)
var_dump($redis->EXISTS('greeting'));   # greeting取而代之 //bool(true)

# 情况2:当key不存在时,返回错误 ,php返回false;
var_dump($redis->RENAME('fake_key','never_exists'));  //bool(false)

# 情况3:newkey已存在时,RENAME会覆盖旧newkey
$redis->SET('pc',"lenovo");
$redis->SET('personal_computer',"dell"); 
var_dump($redis->RENAME('pc','personal_computer')); //bool(true)
var_dump($redis->GET('pc')); //(nil)   bool(false)
var_dump($redis->GET('personal_computer'));  # dell“没有”了 //string(6) "lenovo"

 

RENAMENX

RENAMENX key newkey

当且仅当newkey不存在时,将key改为newkey

出错的情况和RENAME一样(key不存在时报错)。

时间复杂度:
O(1)

返回值:
修改成功时,返回1

如果newkey已经存在,返回0

//RENAMENX
echo '<br><br>RENAMENX<br>';

# 情况1:newkey不存在,成功
$redis->SET('player',"MPlyaer");
$redis->EXISTS('best_player'); //int(0)
var_dump($redis->RENAMENX('player','best_player')); // bool(true) 

# 情况2:newkey存在时,失败
$redis->SET('animal',"bear");
$redis->SET('favorite_animal', "butterfly");

var_dump($redis->RENAMENX('animal', 'favorite_animal'));// bool(false)

var_dump($redis->get('animal')); //string(4) "bear"
var_dump($redis->get('favorite_animal')); //string(9) "butterfly"

TYPE

TYPE key

返回key所储存的值的类型。

时间复杂度:
O(1)

返回值:
none(key不存在) int(0)

string(字符串) int(1)

list(列表) int(3)

set(集合) int(2)

zset(有序集) int(4)

hash(哈希表) int(5)

 

//TYPE
$redis->flushALL();
echo '<br><br>TYPE<br>';

var_dump($redis->TYPE('fake_key')); //none /int(0)

$redis->SET('weather',"sunny");  # 构建一个字符串
var_dump($redis->TYPE('weather'));//string / int(1)

$redis->SADD('pat',"dog");  # 构建一个集合
var_dump($redis->TYPE('pat')); //set /int(2)

$redis->LPUSH('book_list',"programming in scala");  # 构建一个列表
var_dump($redis->TYPE('book_list'));//list / int(3) 

$redis->ZADD('pats',1,'cat');  # 构建一个zset (sorted set) // int(1)
$redis->ZADD('pats',2,'dog');
$redis->ZADD('pats',3,'pig');
var_dump($redis->zRange('pats',0,-1)); // array(3) { [0]=> string(3) "cat" [1]=> string(3) "dog" [2]=> string(3) "pig" }
var_dump($redis->TYPE('pats')); //zset / int(4)

$redis->HSET('website','google','www.g.cn');   # 一个新域
var_dump($redis->HGET('website','google')); //string(8) "www.g.cn"
var_dump($redis->TYPE('website')); //hash /int(5)

EXPIRE

EXPIRE key seconds

为给定key设置生存时间。

key过期时,它会被自动删除。

在Redis中,带有生存时间的key被称作“易失的”(volatile)。

 

在低于2.1.3版本的Redis中,已存在的生存时间不可覆盖。

从2.1.3版本开始,key的生存时间可以被更新,也可以被PERSIST命令移除。(详情参见 http://redis.io/topics/expire)。

 

时间复杂度:
O(1)

返回值:
设置成功返回1

key不存在或者不能为key设置生存时间时(比如在低于2.1.3中你尝试更新key的生存时间),返回0

//EXPIRE
$redis->select(7);
//$redis->flushdb();

echo '<br><br>EXPIRE<br>';
$redis->SET('cache_page',"www.cnblogs.com/ikodota");
$redis->EXPIRE('cache_page', 30);  # 设置30秒后过期
sleep(6);
echo $redis->TTL('cache_page').'<br>';   # 查看给定key的剩余生存时间 //(integer) 24

$redis->EXPIRE('cache_page', 3000);  # 更新生存时间,3000秒
sleep(4);
echo $redis->TTL('cache_page').'<br>';   //(integer) 2996

 

EXPIREAT

EXPIREAT key timestamp

EXPIREAT的作用和EXPIRE一样,都用于为key设置生存时间。

不同在于EXPIREAT命令接受的时间参数是UNIX时间戳(unix timestamp)。

时间复杂度:
O(1)

返回值:
如果生存时间设置成功,返回1

key皇牌天下投注网,不存在或没办法设置生存时间,返回0

 

//EXPIREAT
echo '<br><br>EXPIREAT<br>';
$redis->SET('cache','www.google.com');
echo $redis->EXPIREAT('cache','1355292000'); # 这个key将在2012.12.12过期

echo ($redis->TTL('cache')); //return 124345085

OBJECT

OBJECT subcommand [arguments [arguments]]

OBJECT命令允许从内部察看给定key的Redis对象。

它通常用在除错(debugging)或者了解为了节省空间而对key使用特殊编码的情况。

当将Redis用作缓存程序时,你也可以通过OBJECT命令中的信息,决定key的驱逐策略(eviction policies)。

OBJECT命令有多个子命令:

  • OBJECT REFCOUNT <key>返回给定key引用所储存的值的次数。此命令主要用于除错。
  • OBJECT ENCODING <key>返回给定key锁储存的值所使用的内部表示(representation)。
  • OBJECT IDLETIME <key>返回给定key自储存以来的空转时间(idle, 没有被读取也没有被写入),以秒为单位。

对象可以以多种方式编码:

  • 字符串可以被编码为raw(一般字符串)或int(用字符串表示64位数字是为了节约空间)。
  • 列表可以被编码为ziplistlinkedlistziplist是为节约大小较小的列表空间而作的特殊表示。
  • 集合可以被编码为intset或者hashtableintset是只储存数字的小集合的特殊表示。
  • 哈希表可以编码为zipmap或者hashtablezipmap是小哈希表的特殊表示。
  • 有序集合可以被编码为ziplist或者skiplist格式。ziplist用于表示小的有序集合,而skiplist则用于表示任何大小的有序集合。

假如你做了什么让Redis没办法再使用节省空间的编码时(比如将一个只有1个元素的集合扩展为一个有100万个元素的集合),特殊编码类型(specially encoded types)会自动转换成通用类型(general type)。

时间复杂度:
O(1)

返回值:
REFCOUNTIDLETIME返回数字。

ENCODING返回相应的编码类型。

//OBJECT
$redis->select(8);
echo '<br><br>OBJECT<br>';
$redis->SET('game',"WOW");  # 设置一个字符串
$redis->OBJECT('REFCOUNT','game');  # 只有一个引用

//sleep(5);
echo $redis->OBJECT('IDLETIME','game');  # 等待一阵。。。然后查看空转时间 //(integer) 10
//echo $redis->GET('game');  # 提取game, 让它处于活跃(active)状态  //return WOW
//echo $redis->OBJECT('IDLETIME','game');  # 不再处于空转 //(integer) 0
var_dump($redis->OBJECT('ENCODING','game'));  # 字符串的编码方式 //string(3) "raw"
$redis->SET('phone',15820123123);  # 大的数字也被编码为字符串
var_dump($redis->OBJECT('ENCODING','phone')); //string(3) "raw"
$redis->SET('age',20);  # 短数字被编码为int
var_dump($redis->OBJECT('ENCODING','age')); //string(3) "int"

PERSIST
PERSIST key

 

移除给定key的生存时间。

 

时间复杂度:
O(1)

返回值:
当生存时间移除成功时,返回1.

如果key不存在或key没有设置生存时间,返回0

 

//PERSIST
echo '<br><br>PERSIST<br>';
$redis->SET('time_to_say_goodbye',"886...");
$redis->EXPIRE('time_to_say_goodbye', 300);
sleep(3);
echo $redis->TTL('time_to_say_goodbye'); # (int) 297
echo '<br>';

$redis->PERSIST('time_to_say_goodbye');  # 移除生存时间
echo $redis->TTL('time_to_say_goodbye');  # 移除成功  //int(-1)

SORT

 

SORT key [BY pattern] [LIMIT offset count] [GET pattern [GET pattern ...]] [ASC | DESC] [ALPHA] [STORE destination]

排序,分页等
参数

array(
‘by’ => ‘some_pattern_*’,
‘limit’ => array(0, 1),
‘get’ => ‘some_other_pattern_*’ or an array of patterns,
‘sort’ => ‘asc’ or ‘desc’,
‘alpha’ => TRUE,
‘store’ => ‘external-key’
)

返回或保存给定列表、集合、有序集合key中经过排序的元素。

排序默认以数字作为对象,值被解释为双精度浮点数,然后进行比较。

 

一般SORT用法

最简单的SORT使用方法是SORT key

假设today_cost是一个保存数字的列表,SORT命令默认会返回该列表值的递增(从小到大)排序结果。

 

# 将数据一一加入到列表中
$redis->LPUSH('today_cost', 30);
$redis->LPUSH('today_cost', 1.5);
$redis->LPUSH('today_cost', 10);
$redis->LPUSH('today_cost', 8);
# 排序
var_dump($redis->SORT('today_cost')); //array(4) { [0]=> string(3) "1.5" [1]=> string(1) "8" [2]=> string(2) "10" [3]=> string(2) "30" }

当数据集中保存的是字符串值时,你可以用ALPHA修饰符(modifier)进行排序。

# 将数据一一加入到列表中
$redis->LPUSH('website', "www.reddit.com");
$redis->LPUSH('website', "www.slashdot.com");
$redis->LPUSH('website', "www.infoq.com");
# 默认排序
var_dump($redis->SORT('website'));//array(3) { [0]=> string(13) "www.infoq.com" [1]=> string(16) "www.slashdot.com" [2]=> string(14) "www.reddit.com" }

# 按字符排序 ALPHA=true
var_dump($redis->SORT('website', array('ALPHA'=>TRUE))); //array(3) { [0]=> string(13) "www.infoq.com" [1]=> string(14) "www.reddit.com" [2]=> string(16) "www.slashdot.com" }

如果你正确设置了!LC_COLLATE环境变量的话,Redis能识别UTF-8编码。

排序之后返回的元素数量可以通过LIMIT修饰符进行限制。

LIMIT修饰符接受两个参数:offsetcount

offset指定要跳过的元素数量,count指定跳过offset个指定的元素之后,要返回多少个对象。

以下例子返回排序结果的前5个对象(offset0表示没有元素被跳过)。

# 将数据一一加入到列表中
$redis->LPUSH('rank', 30); //(integer) 1
$redis->LPUSH('rank', 56); //(integer) 2
$redis->LPUSH('rank', 42); //(integer) 3
$redis->LPUSH('rank', 22); //(integer) 4
$redis->LPUSH('rank', 0);  //(integer) 5
$redis->LPUSH('rank', 11); //(integer) 6
$redis->LPUSH('rank', 32); //(integer) 7
$redis->LPUSH('rank', 67); //(integer) 8
$redis->LPUSH('rank', 50); //(integer) 9
$redis->LPUSH('rank', 44); //(integer) 10
$redis->LPUSH('rank', 55); //(integer) 11

# 排序
$redis_sort_option=array('LIMIT'=>array(0,5));
var_dump($redis->SORT('rank',$redis_sort_option));   # 返回排名前五的元素 // array(5) { [0]=> string(1) "0" [1]=> string(2) "11" [2]=> string(2) "22" [3]=> string(2) "30" [4]=> string(2) "32" }

修饰符可以组合使用。以下例子返回降序(从大到小)的前5个对象。

$redis_sort_option=array(
            'LIMIT'=>array(0,5),
            'SORT'=>'DESC'
            );
var_dump($redis->SORT('rank',$redis_sort_option)); //array(5) { [0]=> string(2) "67" [1]=> string(2) "56" [2]=> string(2) "55" [3]=> string(2) "50" [4]=> string(2) "44" }

 

使用外部key进行排序

有时候你会希望使用外部的key作为权重来比较元素,代替默认的对比方法。

假设现在有用户(user)数据如下:

很有用;以下是redis官方提供的命令使用技巧:

id     name    level

1    admin     9999
2    huangz   10
59230  jack        3
222    hacker      9999

id数据保存在key名为user_id的列表中。
name数据保存在key名为user_name_{id}的列表中
level数据保存在user_level_{id}的key中。

# 先将要使用的数据加入到数据库中

# admin
$redis->LPUSH('user_id', 1);//(integer) 1
$redis->SET('user_name_1', 'admin');
$redis->SET('user_level_1',9999);

# huangz
$redis->LPUSH('user_id', 2);//(integer) 2
$redis->SET('user_name_2', 'huangz');
$redis->SET('user_level_2', 10);

# jack
$redis->LPUSH('user_id', 59230);//(integer) 3
$redis->SET('user_name_59230','jack');
$redis->SET('user_level_59230', 3);

# hacker
$redis->LPUSH('user_id', 222);  //(integer) 4
$redis->SET('user_name_222', 'hacker');
$redis->SET('user_level_222', 9999);

 

如果希望按level从大到小排序user_id,可以使用以下命令:

$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC'
            );
var_dump($redis->SORT('user_id',$redis_sort_option)); //array(4) { [0]=> string(3) "222" [1]=> string(1) "1" [2]=> string(1) "2" [3]=> string(5) "59230" }

#---------------------------
#1) "222"    # hacker
#2) "1"      # admin
#3) "2"      # huangz
#4) "59230"  # jack

但是有时候只是返回相应的id没有什么用,你可能更希望排序后返回id对应的用户名,这样更友好一点,使用GET选项可以做到这一点:

 

$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>'user_name_*'
            );
var_dump($redis->SORT('user_id', $redis_sort_option)); //array(4) { [0]=> string(6) "hacker" [1]=> string(5) "admin" [2]=> string(6) "huangz" [3]=> string(4) "jack" }

#1) "hacker"
#2) "admin"
#3) "huangz"
#4) "jack"

可以多次地、有序地使用GET操作来获取更多外部key

比如你不但希望获取用户名,还希望连用户的密码也一并列出,可以使用以下命令:

 

# 先添加一些测试数据
$redis->SET('user_password_222', "hey,im in");
$redis->SET('user_password_1', "a_long_long_password");
$redis->SET('user_password_2', "nobodyknows");
$redis->SET('user_password_59230', "jack201022");

# 获取name和password
$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('user_name_*','user_password_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(8) { [0]=> string(6) "hacker" [1]=> string(9) "hey,im in" [2]=> string(5) "admin" [3]=> string(20) "a_long_long_password" [4]=> string(6) "huangz" [5]=> string(11) "nobodyknows" [6]=> string(4) "jack" [7]=> string(10) "jack201022" }

#------------------------------------
#1) "hacker"       # 用户名
#2) "hey,im in"    # 密码
#3) "jack"
#4) "jack201022"
#5) "huangz"
#6) "nobodyknows"
#7) "admin"
#8) "a_long_long_password"

# 注意GET操作是有序的,GET user_name_* GET user_password_* 和 GET user_password_* GET user_name_*返回的结果位置不同

 

# 获取name和password 注意GET操作是有序的
$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('user_password_*','user_name_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));// array(8) { [0]=> string(9) "hey,im in" [1]=> string(6) "hacker" [2]=> string(20) "a_long_long_password" [3]=> string(5) "admin" [4]=> string(11) "nobodyknows" [5]=> string(6) "huangz" [6]=> string(10) "jack201022" [7]=> string(4) "jack" }

GET还有一个特殊的规则——"GET #",用于获取被排序对象(我们这里的例子是user_id)的当前元素。

比如你希望user_idlevel排序,还要列出idnamepassword,可以使用以下命令:

 

$redis_sort_option=array('BY'=>'user_level_*',
            'SORT'=>'DESC',
            'GET'=>array('#','user_password_*','user_name_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(12) { [0]=> string(3) "222" [1]=> string(9) "hey,im in" [2]=> string(6) "hacker" [3]=> string(1) "1" [4]=> string(20) "a_long_long_password" [5]=> string(5) "admin" [6]=> string(1) "2" [7]=> string(11) "nobodyknows" [8]=> string(6) "huangz" [9]=> string(5) "59230" [10]=> string(10) "jack201022" [11]=> string(4) "jack" }

#--------------------------------------------------------------
#1) "222"          # id
#2) "hacker"       # name
#3) "hey,im in"    # password
#4) "1"
#5) "admin"
#6) "a_long_long_password"
#7) "2"
#8) "huangz"
#9) "nobodyknows"
#10) "59230"
#11) "jack"
#12) "jack201022"

只获取对象而不排序

BY修饰符可以将一个不存在的key当作权重,让SORT跳过排序操作。

该方法用于你希望获取外部对象而又不希望引起排序开销时使用。

 

# 确保fake_key不存在
$redis->EXISTS('fake_key');//(integer) 0

# 以fake_key作BY参数,不排序,只GET name 和 GET password
$redis_sort_option=array('BY'=>'fake_key',
            'SORT'=>'DESC',
            'GET'=>array('#','user_name_*','user_password_*')
            );
var_dump($redis->SORT('user_id',$redis_sort_option));//array(12) { [0]=> string(3) "222" [1]=> string(6) "hacker" [2]=> string(9) "hey,im in" [3]=> string(5) "59230" [4]=> string(4) "jack" [5]=> string(10) "jack201022" [6]=> string(1) "2" [7]=> string(6) "huangz" [8]=> string(11) "nobodyknows" [9]=> string(1) "1" [10]=> string(5) "admin" [11]=> string(20) "a_long_long_password" }

#----------------------------------------------
#1) "222"        # id
#2) "hacker"     # user_name
#3) "hey,im in"  # password
#4) "59230"
#5) "jack"
#6) "jack201022"
#7) "2"
#8) "huangz"
#9) "nobodyknows"
#10) "1"
#11) "admin"
#12) "a_long_long_password"

保存排序结果

默认情况下,SORT操作只是简单地返回排序结果,如果你希望保存排序结果,可以给STORE选项指定一个key作为参数,排序结果将以列表的形式被保存到这个key上。(若指定key已存在,则覆盖。)

$redis->EXISTS('user_info_sorted_by_level');  # 确保指定key不存在   //(integer) 0
$redis_sort_option=array('BY'=>'user_level_*',
            'GET'=>array('#','user_name_*','user_password_*'),
            'STORE'=>'user_info_sorted_by_level'
            );

var_dump($redis->SORT('user_id',$redis_sort_option)); //int(12)
var_dump($redis->LRANGE('user_info_sorted_by_level', 0 ,11));  # 查看排序结果  //array(12) { [0]=> string(5) "59230" [1]=> string(4) "jack" [2]=> string(10) "jack201022" [3]=> string(1) "2" [4]=> string(6) "huangz" [5]=> string(11) "nobodyknows" [6]=> string(3) "222" [7]=> string(6) "hacker" [8]=> string(9) "hey,im in" [9]=> string(1) "1" [10]=> string(5) "admin" [11]=> string(20) "a_long_long_password" }

#-----------------------------------------------------------------
#1) "59230"
#2) "jack"
#3) "jack201022"
#4) "2"
#5) "huangz"
#6) "nobodyknows"
#7) "222"
#8) "hacker"
#9) "hey,im in"
#10) "1"
#11) "admin"
#12) "a_long_long_password"

一个有趣的用法是将SORT结果保存,用EXPIRE为结果集设置生存时间,这样结果集就成了SORT操作的一个缓存。

这样就不必频繁地调用SORT操作了,只有当结果集过期时,才需要再调用一次SORT操作。

有时候为了正确实现这一用法,你可能需要加锁以避免多个客户端同时进行缓存重建(也就是多个客户端,同一时间进行SORT操作,并保存为结果集),具体参见SETNX命令。

在GET和BY中使用哈希表

可以使用哈希表特有的语法,在SORT命令中进行GET和BY操作。

# 假设现在我们的用户表新增了一个serial项来为作为每个用户的序列号
# 序列号以哈希表的形式保存在serial哈希域内。

$redis_hash_testdata_array=array(1=>'23131283',
                2=>'23810573',
                222=>'502342349',
                59230=>'2435829758'
                );

$redis->HMSET('serial',$redis_hash_testdata_array);

# 我们希望以比较serial中的大小来作为排序user_id的方式
$redis_sort_option=array('BY'=>'*->serial');
var_dump($redis->SORT('user_id', $redis_sort_option)); //array(4) { [0]=> string(3) "222" [1]=> string(5) "59230" [2]=> string(1) "2" [3]=> string(1) "1" }

#----------------------------------------
#1) "222"
#2) "59230"
#3) "2"
#4) "1"

 

符号"->"用于分割哈希表的关键字(key name)和索引域(hash field),格式为"key->field"

除此之外,哈希表的BYGET操作和上面介绍的其他数据结构(列表、集合、有序集合)没有什么不同。

时间复杂度:
O(N M*log(M)),N为要排序的列表或集合内的元素数量,M为要返回的元素数量。

如果只是使用SORT命令的GET选项获取数据而没有进行排序,时间复杂度O(N)。

返回值:
没有使用STORE参数,返回列表形式的排序结果。

使用STORE参数,返回排序结果的元素数量。

 

下载地址如下:

字符串(String)

SET

SET key value

将字符串值value关联到key

如果key已经持有其他值,SET就覆写旧值,无视类型。

时间复杂度:O(1)返回值:总是返回OK(TRUE),因为SET不可能失败。

# 情况1:对字符串类型的key进行SET
$redis->SET('apple', 'www.apple.com');#OK  //bool(true)
$redis->GET('apple');//"www.apple.com"

# 情况2:对非字符串类型的key进行SET
$redis->LPUSH('greet_list', "hello");  # 建立一个列表 #(integer) 1 //int(1)
$redis->TYPE('greet_list');#list //int(3)

$redis->SET('greet_list', "yooooooooooooooooo");   # 覆盖列表类型 #OK //bool(true)
$redis->TYPE('greet_list');#string //int(1)

 

SETNX

SETNX key value

key的值设为value,当且仅当key不存在。

若给定的key已经存在,则SETNX不做任何动作。

SETNX是”SET if Not eXists”(如果不存在,则SET)的简写。

时间复杂度:
O(1)

返回值:
设置成功,返回1

设置失败,返回0

//SETNX
echo '<br><br>SETNX<br>';
$redis->EXISTS('job');  # job不存在 //bool(false);
$redis->SETNX('job', "programmer");  # job设置成功 //bool(true)
$redis->SETNX('job', "code-farmer");  # job设置失败 //bool(false)
echo $redis->GET('job');  # 没有被覆盖 //"programmer"

设计模式(Design pattern): 将SETNX用于加锁(locking)

SETNX可以用作加锁原语(locking primitive)。比如说,要对关键字(key)foo加锁,客户端可以尝试以下方式:

SETNX lock.foo <current Unix time   lock timeout   1>

如果SETNX返回1,说明客户端已经获得了锁,key设置的unix时间则指定了锁失效的时间。之后客户端可以通过DEL lock.foo来释放锁。

如果SETNX返回0,说明key已经被其他客户端上锁了。如果锁是非阻塞(non blocking lock)的,我们可以选择返回调用,或者进入一个重试循环,直到成功获得锁或重试超时(timeout)。

处理死锁(deadlock)

上面的锁算法有一个问题:如果因为客户端失败、崩溃或其他原因导致没有办法释放锁的话,怎么办?

这种状况可以通过检测发现——因为上锁的key保存的是unix时间戳,假如key值的时间戳小于当前的时间戳,表示锁已经不再有效。

但是,当有多个客户端同时检测一个锁是否过期并尝试释放它的时候,我们不能简单粗暴地删除死锁的key,再用SETNX上锁,因为这时竞争条件(race condition)已经形成了:

  • C1和C2读取lock.foo并检查时间戳,SETNX都返回0,因为它已经被C3锁上了,但C3在上锁之后就崩溃(crashed)了。
  • C1向lock.foo发送DEL命令。
  • C1向lock.foo发送SETNX并成功。
  • C2向lock.foo发送DEL命令。
  • C2向lock.foo发送SETNX并成功。
  • 出错:因为竞争条件的关系,C1和C2两个都获得了锁。

幸好,以下算法可以避免以


https://github.com/owlient/phpredis(支持redis 2.0.4)

Redis::__construct构造函数
$redis = new Redis();

connect, open 链接redis服务
参数
host: string,服务地址
port: int,端口号
timeout: float,链接时长 (可选, 默认为 0 ,不限链接时间)
注: 在redis.conf中也有时间,默认为300

pconnect, popen 不会主动关闭的链接
参考上面

setOption 设置redis模式

getOption 查看redis设置的模式

ping 查看连接状态

 

KEY相关操作

DEL

移除给定的一个或多个key

如果key不存在,则忽略该命令。

时间复杂度:
O(N),N为要移除的key的数量。

移除单个字符串类型的key,时间复杂度为O(1)。

移除单个列表、集合、有序集合或哈希表类型的key,时间复杂度为O(M),M为以上数据结构内的元素数量。

返回值:
被移除key的数量。

 

皇牌天下投注网 1

皇牌天下投注网 2

皇牌天下投注网 3

//DEL
# 情况1: 删除单个key
$redis->set('myname','ikodota');
echo $redis->get('myname').'<br>'; # 返回:ikodota

$redis->del('myname');# 返回 TRUE(1)
var_dump($redis->get('myname')); # 返回 bool(false)

# 情况2: 删除一个不存在的key
if(!$redis->exists('fake_key')) # 不存在
var_dump($redis->del('fake_key')); # 返回 int(0)

# 情况3: 同时删除多个key
$array_mset=array('first_key'=>'first_val',
          'second_key'=>'second_val',
          'third_key'=>'third_val');
$redis->mset($array_mset); #用MSET一次储存多个值
$array_mget=array('first_key','second_key','third_key');
var_dump($redis->mget($array_mget)); #一次返回多个值 //array(3) { [0]=> string(9) "first_val" [1]=> string(10) "second_val" [2]=> string(9) "third_val" }

$redis->del($array_mget); #同时删除多个key
var_dump($redis->mget($array_mget)); #返回 array(3) { [0]=> bool(false) [1]=> bool(false) [2]=> bool(false) }

皇牌天下投注网 4

皇牌天下投注网 5

皇牌天下投注网 6

 

KEYS

KEYS pattern

查找符合给定模式的key

KEYS *命中数据库中所有key

KEYS h?llo命中hello, hallo and hxllo等。

KEYS h*llo命中hlloheeeeello等。

KEYS h[ae]llo命中hellohallo,但不命中hillo

特殊符号用""隔开

时间复杂度:
O(N),N为数据库中key的数量。

返回值:
符合给定模式的key列表。

警告 :KEYS的速度非常快,但在一个大的数据库中使用它仍然可能造成性能问题,如果你需要从一个数据集中查找特定的key,你最好还是用集合(Set)

 

皇牌天下投注网 7

皇牌天下投注网 8

皇牌天下投注网 9

//KEYS
#$redis->FLUSHALL();
$array_mset_keys=array('one'=>'1',
          'two'=>'2',
          'three '=>'3',
          'four'=>'4');
$redis->mset($array_mset_keys); #用MSET一次储存多个值
var_dump($redis->keys('*o*')); //array(3) { [0]=> string(4) "four" [1]=> string(3) "two" [2]=> string(3) "one" }
var_dump($redis->keys('t??')); //array(1) { [0]=> string(3) "two" }
var_dump($redis->keys('t[w]*')); //array(1) { [0]=> string(3) "two" }
print_r($redis->keys('*')); //Array ( [0] => four [1] => three [2] => two [3] => one )

皇牌天下投注网 10

皇牌天下投注网 11

皇牌天下投注网 12

 

RANDOMKEY

从当前数据库中随机返回(不删除)一个key

时间复杂度:
O(1)

返回值:
当数据库不为空时,返回一个key

当数据库为空时,返回nil。

 

皇牌天下投注网 13

皇牌天下投注网 14

皇牌天下投注网 15

//RANDOMKEY
$redis->FLUSHALL();
# 情况1:数据库不为空
$array_mset_randomkey=array('fruit'=>'apple',
                'drink'=>'beer',
                'food'=>'cookis');
$redis->mset($array_mset_randomkey);
echo $redis->randomkey(); 
print_r($redis->keys('*')); # 查看数据库内所有key,证明RANDOMKEY并不删除key//Array ( [0] => food [1] => drink [2] => fruit )

# 情况2:数据库为空
$redis->flushdb();  # 删除当前数据库所有key
var_dump($redis-> randomkey()); //bool(false)

皇牌天下投注网 16

皇牌天下投注网 17

皇牌天下投注网 18

 

TTLTTL key

返回给定key的剩余生存时间(time to live)(以秒为单位)。

时间复杂度:
O(1)

返回值:
key的剩余生存时间(以秒为单位)。

key不存在或没有设置生存时间时,返回-1 。

 

皇牌天下投注网 19

皇牌天下投注网 20

皇牌天下投注网 21

//TTL
# 情况1:带TTL的key
$redis->flushdb();
//$redis->set('name','ikodota'); # 设置一个key
$redis->expire('name',30);  # 设置生存时间为30秒 //return (integer) 1
echo $redis->get('name'); //return ikodota
echo $redis->ttl('name'); //(integer) 25

//echo $redis->ttl('name');  # 30秒过去,name过期 //(integer) -1
var_dump($redis->get('name')); # 过期的key将被删除 //return bool(false);

# 情况2:不带TTL的key
$redis->set('site','wikipedia.org');//OK
var_dump($redis->ttl('site'));//int(-1)

# 情况3:不存在的key
$redis->EXISTS('not_exists_key');//int(0)
var_dump($redis->TTL('not_exists_key'));//int(-1)

皇牌天下投注网 22

皇牌天下投注网 23

皇牌天下投注网 24

 

EXISTS

EXISTS key

检查给定key是否存在。

时间复杂度:
O(1)

返回值:
key存在,返回1,否则返回0

皇牌天下投注网 25

皇牌天下投注网 26

//EXISTS
echo '<br>EXISTS<br>';
$redis->set('db',"redis"); //bool(true) 
var_dump($redis->exists('db'));  # key存在 //bool(true) 
$redis->del('db');   # 删除key //int(1)
var_dump($redis->exists('db'))  # key不存在 //bool(false)

皇牌天下投注网 27

皇牌天下投注网 28

 

MOVE
MOVE key db

将当前数据库(默认为0)的key移动到给定的数据库db当中。

如果当前数据库(源数据库)和给定数据库(目标数据库)有相同名字的给定key,或者key不存在于当前数据库,那么MOVE没有任何效果。

因此,也可以利用这一特性,将MOVE当作锁(locking)原语。

时间复杂度:
O(1)

返回值:
移动成功返回1,失败则返回0

皇牌天下投注网 29

皇牌天下投注网 30

皇牌天下投注网 31

//MOVE
echo '<br><br>MOVE<br>';
# 情况1: key存在于当前数据库
$redis->SELECT(0);  # redis默认使用数据库0,为了清晰起见,这里再显式指定一次。//OK
$redis->SET('song',"secret base - Zone"); //OK
var_dump ($redis->MOVE('song',1));  # 将song移动到数据库1 //bool(true)

# 情况2:当key不存在的时候
$redis->SELECT(1);
var_dump ($redis->EXISTS('fake_key'));//bool(false);
var_dump($redis->MOVE('fake_key', 0));  # 试图从数据库1移动一个不存在的key到数据库0,失败) //bool(false)

$redis->SELECT(0); # 使用数据库0
var_dump($redis->EXISTS('fake_key'));  # 证实fake_key不存在 //bool(false)

# 情况3:当源数据库和目标数据库有相同的key时

$redis->SELECT(0);  # 使用数据库0
$redis->SET('favorite_fruit',"banana");

$redis->SELECT(1);  # 使用数据库1
$redis->SET('favorite_fruit',"apple");

$redis->SELECT(0);  # 使用数据库0,并试图将favorite_fruit移动到数据库1
var_dump($redis->MOVE('favorite_fruit',1));  # 因为两个数据库有相同的key,MOVE失败 //return bool(false)
echo $redis->GET('favorite_fruit');  # 数据库0的favorite_fruit没变 //return banana

$redis->SELECT(1);
echo $redis->GET('favorite_fruit');   # 数据库1的favorite_fruit也是 //return apple

皇牌天下投注网 32

皇牌天下投注网 33

皇牌天下投注网 34

 

RENAME 

RENAME key newkey

key改名为newkey

keynewkey相同或者key不存在时,返回一个错误。

newkey已经存在时,RENAME命令将覆盖旧值。

时间复杂度:
O(1)

返回值:
改名成功时提示OK,失败时候返回一个错误。

皇牌天下投注网 35

皇牌天下投注网 36

皇牌天下投注网 37

//RENAME
echo '<br><br>RENAME<br>';
# 情况1:key存在且newkey不存在
$redis->SET('message',"hello world");
var_dump($redis->RENAME('message','greeting'));  //bool(true)
var_dump($redis->EXISTS('message'));  # message不复存在 //bool(false)
var_dump($redis->EXISTS('greeting'));   # greeting取而代之 //bool(true)

# 情况2:当key不存在时,返回错误 ,php返回false;
var_dump($redis->RENAME('fake_key','never_exists'));  //bool(false)

# 情况3:newkey已存在时,RENAME会覆盖旧newkey
$redis->SET('pc',"lenovo");
$redis->SET('personal_computer',"dell"); 
var_dump($redis->RENAME('pc','personal_computer')); //bool(true)
var_dump($redis->GET('pc')); //(nil)   bool(false)
var_dump($redis->GET('personal_computer'));  # dell“没有”了 //string(6) "lenovo"

皇牌天下投注网 38

皇牌天下投注网 39

皇牌天下投注网 40

 

RENAMENX

RENAMENX key newkey

当且仅当newkey不存在时,将key改为newkey

出错的情况和RENAME一样(key不存在时报错)。

时间复杂度:
O(1)

返回值:
修改成功时,返回1

如果newkey已经存在,返回0

皇牌天下投注网 41

皇牌天下投注网 42

皇牌天下投注网 43

//RENAMENX
echo '<br><br>RENAMENX<br>';

# 情况1:newkey不存在,成功
$redis->SET('player',"MPlyaer");
$redis->EXISTS('best_player'); //int(0)
var_dump($redis->RENAMENX('player','best_player')); // bool(true) 

# 情况2:newkey存在时,失败
$redis->SET('animal',"bear");
$redis->SET('favorite_animal', "butterfly");

var_dump($redis->RENAMENX('animal', 'favorite_animal'));// bool(false)

var_dump($redis->get('animal')); //string(4) "bear"
var_dump($redis->get('favorite_animal')); //string(9) "butterfly"

皇牌天下投注网 44

皇牌天下投注网 45

皇牌天下投注网 46

TYPE

TYPE key

返回key所储存的值的类型。

时间复杂度:
O(1)

返回值:
none(key不存在) int(0)

本文由皇牌天下投注网发布于计算机教程,转载请注明出处:phpredis中文手册&mdash;&mdash;《redis中文手册》 php版

关键词:

上一篇:AjaxFileUploader上传插件 兼容性好

下一篇:没有了

最火资讯