@[TOC](PHP操作Redis命令大全)
PHP操作Redis命令大全
一、前言
Redis是一个开源的高性能键值对存储数据库,常用于缓存、消息队列、会话管理等场景。本文整理了PHP操作Redis的常用命令,帮助开发者快速上手。
**本文适用环境:**
-
PHP 7.0+
-
Redis 5.0+
-
phpredis扩展 或 predis/predis 库
二、环境准备
2.1 安装phpredis扩展
```bash
Ubuntu/Debian
sudo apt-get install php-redis
CentOS/RHEL
sudo yum install php-pecl-redis
或者使用PECL安装
pecl install redis
```
2.2 使用Composer安装Predis
```bash
composer require predis/predis
```
2.3 连接Redis
```php
<?php
// 方式一:phpredis扩展
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('your_password'); // 如果有密码
// 方式二:Predis库
require 'vendor/autoload.php';
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
]);
```
三、字符串(String)操作
3.1 基础操作
```php
<?php
// 设置键值
$redis->set('name', '张三');
$redis->set('age', 25);
// 获取值
name = redis->get('name');
echo $name; // 输出: 张三
// 设置过期时间(单位:秒)
$redis->setex('token', 3600, 'abc123');
// 设置多个键值
$redis->mset([
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3'
]);
// 获取多个值
values = redis->mget(['key1', 'key2', 'key3']);
```
3.2 数值操作
```php
<?php
// 自增
$redis->set('counter', 0);
$redis->incr('counter'); // 值变为1
$redis->incrBy('counter', 5); // 值变为6
// 自减
$redis->decr('counter'); // 值变为5
$redis->decrBy('counter', 3); // 值变为2
// 浮点数操作
$redis->set('price', 9.99);
$redis->incrByFloat('price', 0.01); // 值变为10.00
```
3.3 其他操作
```php
<?php
// 追加内容
$redis->set('greeting', 'Hello');
$redis->append('greeting', ' World'); // 值变为"Hello World"
// 获取字符串长度
length = redis->strlen('greeting'); // 返回11
// 获取子字符串
substr = redis->getRange('greeting', 0, 4); // 返回"Hello"
// 设置子字符串
$redis->setRange('greeting', 6, 'Redis'); // 值变为"Hello Redis"
```
四、哈希(Hash)操作
4.1 基础操作
```php
<?php
// 设置单个字段
$redis->hSet('user:1', 'name', '张三');
$redis->hSet('user:1', 'age', 25);
$redis->hSet('user:1', 'email', 'zhangsan@example.com');
// 获取单个字段
name = redis->hGet('user:1', 'name');
// 设置多个字段
$redis->hMSet('user:2', [
'name' => '李四',
'age' => 30,
'email' => 'lisi@example.com'
]);
// 获取多个字段
userInfo = redis->hMGet('user:2', ['name', 'age', 'email']);
```
4.2 查询操作
```php
<?php
// 获取所有字段和值
allFields = redis->hGetAll('user:1');
// 获取所有字段名
fields = redis->hKeys('user:1');
// 获取所有字段值
values = redis->hVals('user:1');
// 判断字段是否存在
exists = redis->hExists('user:1', 'name'); // 返回true/false
// 获取字段数量
count = redis->hLen('user:1');
```
4.3 数值操作
```php
<?php
// 字段值自增
$redis->hIncrBy('user:1', 'age', 1); // age增加1
$redis->hIncrByFloat('user:1', 'score', 0.5); // score增加0.5
// 删除字段
$redis->hDel('user:1', 'email');
```
五、列表(List)操作
5.1 添加元素
```php
<?php
// 左侧添加(头部)
$redis->lPush('queue', 'task1');
$redis->lPush('queue', 'task2'); // 列表: [task2, task1]
// 右侧添加(尾部)
$redis->rPush('queue', 'task3'); // 列表: [task2, task1, task3]
// 批量添加
$redis->lPush('queue', 'task4', 'task5');
$redis->rPush('queue', 'task6', 'task7');
```
5.2 获取元素
```php
<?php
// 获取列表长度
length = redis->lLen('queue');
// 获取指定范围元素
items = redis->lRange('queue', 0, -1); // 获取全部
items = redis->lRange('queue', 0, 4); // 获取前5个
// 获取指定索引元素
item = redis->lIndex('queue', 0); // 获取第一个元素
```
5.3 弹出元素
```php
<?php
// 左侧弹出
task = redis->lPop('queue'); // 弹出并返回第一个元素
// 右侧弹出
task = redis->rPop('queue'); // 弹出并返回最后一个元素
// 阻塞式弹出(等待超时时间)
result = redis->blPop(['queue1', 'queue2'], 5); // 等待5秒
result = redis->brPop(['queue1', 'queue2'], 5);
```
5.4 其他操作
```php
<?php
// 修剪列表(保留指定范围)
$redis->lTrim('queue', 0, 99); // 只保留前100个元素
// 删除元素
$redis->lRem('queue', 'task1', 1); // 删除1个值为'task1'的元素
// 在指定元素前/后插入
$redis->lInsert('queue', 'before', 'task2', 'new_task');
$redis->lInsert('queue', 'after', 'task2', 'new_task');
```
六、集合(Set)操作
6.1 基础操作
```php
<?php
// 添加元素
$redis->sAdd('tags', 'php');
$redis->sAdd('tags', 'redis', 'mysql', 'nginx'); // 添加多个
// 获取所有元素
tags = redis->sMembers('tags');
// 判断元素是否存在
exists = redis->sIsMember('tags', 'php'); // 返回true/false
// 获取集合元素数量
count = redis->sCard('tags');
// 删除元素
$redis->sRem('tags', 'mysql');
```
6.2 集合运算
```php
<?php
// 准备数据
$redis->sAdd('setA', 'a', 'b', 'c', 'd');
$redis->sAdd('setB', 'b', 'c', 'e', 'f');
// 交集
intersection = redis->sInter('setA', 'setB'); // ['b', 'c']
$redis->sInterStore('result', 'setA', 'setB'); // 结果存入新集合
// 并集
union = redis->sUnion('setA', 'setB'); // ['a', 'b', 'c', 'd', 'e', 'f']
$redis->sUnionStore('result', 'setA', 'setB');
// 差集
diff = redis->sDiff('setA', 'setB'); // ['a', 'd']
$redis->sDiffStore('result', 'setA', 'setB');
```
6.3 随机操作
```php
<?php
// 随机获取元素(不删除)
random = redis->sRandMember('tags'); // 随机获取1个
randoms = redis->sRandMember('tags', 3); // 随机获取3个
// 随机弹出元素(删除)
pop = redis->sPop('tags'); // 随机弹出1个
pops = redis->sPop('tags', 2); // 随机弹出2个
```
七、有序集合(Sorted Set)操作
7.1 基础操作
```php
<?php
// 添加元素(带分数)
$redis->zAdd('rank', 100, 'player1');
$redis->zAdd('rank', 95, 'player2');
$redis->zAdd('rank', 120, 'player3');
// 批量添加
$redis->zAdd('rank',
85, 'player4',
90, 'player5'
);
// 获取元素分数
score = redis->zScore('rank', 'player1'); // 返回100
// 获取元素排名(从0开始,分数从低到高)
rank = redis->zRank('rank', 'player1');
// 获取元素排名(分数从高到低)
rank = redis->zRevRank('rank', 'player1');
```
7.2 范围查询
```php
<?php
// 按分数范围获取(从低到高)
players = redis->zRange('rank', 0, -1); // 获取全部
players = redis->zRange('rank', 0, 2); // 获取前3名
players = redis->zRange('rank', 0, -1, true); // 带分数返回
// 按分数范围获取(从高到低)
players = redis->zRevRange('rank', 0, 2); // 获取前3名(高分在前)
// 按分数值范围获取
players = redis->zRangeByScore('rank', 90, 100); // 分数90-100的玩家
players = redis->zRevRangeByScore('rank', 100, 90);
// 获取分数范围元素数量
count = redis->zCount('rank', 90, 100);
```
7.3 其他操作
```php
<?php
// 获取集合元素数量
count = redis->zCard('rank');
// 删除元素
$redis->zRem('rank', 'player1');
$redis->zRemRangeByScore('rank', 0, 50); // 删除分数0-50的元素
$redis->zRemRangeByRank('rank', 0, 9); // 删除排名0-9的元素
// 增加元素分数
$redis->zIncrBy('rank', 10, 'player1'); // player1分数增加10
```
八、键操作
8.1 键管理
```php
<?php
// 删除键
$redis->del('key1');
$redis->del('key1', 'key2', 'key3');
// 判断键是否存在
exists = redis->exists('key1');
// 设置过期时间(秒)
$redis->expire('key1', 60); // 60秒后过期
$redis->expireAt('key1', time() + 3600); // 指定时间戳过期
// 设置过期时间(毫秒)
$redis->pExpire('key1', 60000);
// 获取剩余过期时间
ttl = redis->ttl('key1'); // 返回秒数,-1表示永不过期,-2表示不存在
pttl = redis->pttl('key1'); // 返回毫秒数
// 移除过期时间
$redis->persist('key1');
```
8.2 键查询
```php
<?php
// 查找键
keys = redis->keys('user:*'); // 匹配user:开头的键
keys = redis->keys('*'); // 获取所有键(生产环境慎用)
// 扫描键(推荐用于大数据量)
$iterator = null;
while (keys = redis->scan($iterator, 'user:*', 100)) {
foreach (keys as key) {
echo $key . "\n";
}
}
// 获取键类型
type = redis->type('key1');
// 返回值: string, list, set, zset, hash, none
// 随机获取一个键
randomKey = redis->randomKey();
```
8.3 键重命名
```php
<?php
// 重命名键
$redis->rename('oldKey', 'newKey');
// 仅在newKey不存在时重命名
$redis->renameNx('oldKey', 'newKey');
```
九、事务操作
```php
<?php
// 开启事务
$redis->multi();
// 添加命令到事务队列
$redis->set('key1', 'value1');
$redis->incr('counter');
$redis->hSet('user:1', 'name', '张三');
// 执行事务
result = redis->exec();
// 取消事务
// $redis->discard();
// 乐观锁(WATCH)
$redis->watch('key1');
value = redis->get('key1');
$redis->multi();
redis-\>set('key1', value + 1);
result = redis->exec(); // 如果key1被其他客户端修改,exec返回false
```
十、发布订阅
10.1 发布消息
```php
<?php
$redis->publish('news', 'Hello, subscribers!');
```
10.2 订阅频道
```php
<?php
// 订阅单个频道
redis-\>subscribe(\['news'\], function (redis, channel, message) {
echo "收到消息: message, 频道: channel\n";
});
// 订阅多个频道
redis-\>subscribe(\['news', 'blog', 'chat'\], function (redis, channel, message) {
echo "收到消息: message, 频道: channel\n";
});
// 模式订阅
redis-\>psubscribe(\['news.\*'\], function (redis, pattern, channel, $message) {
echo "收到消息: message, 频道: channel, 模式: $pattern\n";
});
```
十一、管道操作
管道可以批量执行命令,减少网络往返时间:
```php
<?php
// 使用管道
pipe = redis->multi(Redis::PIPELINE);
for (i = 0; i < 1000; $i++) {
pipe-\>set("key:i", $i);
}
results = pipe->exec();
```
十二、实际应用场景
12.1 用户会话缓存
```php
<?php
class SessionCache {
private $redis;
private $prefix = 'session:';
public function __construct($redis) {
this-\>redis = redis;
}
public function set(sessionId, data, $ttl = 3600) {
key = this->prefix . $sessionId;
this-\>redis-\>setex(key, ttl, json_encode(data));
}
public function get($sessionId) {
key = this->prefix . $sessionId;
data = this->redis->get($key);
return data ? json_decode(data, true) : null;
}
public function delete($sessionId) {
key = this->prefix . $sessionId;
this-\>redis-\>del(key);
}
}
```
12.2 限流器
```php
<?php
class RateLimiter {
private $redis;
public function __construct($redis) {
this-\>redis = redis;
}
// 滑动窗口限流
public function allow(key, maxRequests, $windowSeconds) {
$now = microtime(true);
windowStart = now - $windowSeconds;
// 移除窗口外的请求记录
this-\>redis-\>zRemRangeByScore(key, 0, $windowStart);
// 获取当前窗口内的请求数
current = this->redis->zCard($key);
if (current \< maxRequests) {
// 记录当前请求
this-\>redis-\>zAdd(key, $now, uniqid());
this-\>redis-\>expire(key, $windowSeconds);
return true;
}
return false;
}
}
// 使用
limiter = new RateLimiter(redis);
if ($limiter->allow('api:user:123', 100, 60)) {
// 允许请求
} else {
// 拒绝请求,返回429
http_response_code(429);
echo '请求过于频繁';
}
```
12.3 排行榜
```php
<?php
class Leaderboard {
private $redis;
private $key;
public function __construct(redis, key) {
this-\>redis = redis;
this-\>key = key;
}
// 添加/更新分数
public function addScore(member, score) {
this-\>redis-\>zAdd(this->key, score, member);
}
// 获取前N名
public function getTop($n = 10) {
return this-\>redis-\>zRevRange(this->key, 0, $n - 1, true);
}
// 获取用户排名
public function getRank($member) {
rank = this->redis->zRevRank(this-\>key, member);
return rank !== false ? rank + 1 : null; // 转为1-based排名
}
// 获取用户分数
public function getScore($member) {
return this-\>redis-\>zScore(this->key, $member);
}
}
```
十三、常见问题
Q1: 连接Redis失败怎么办?
**可能原因和解决方案:**
-
Redis服务未启动 - 检查`redis-cli ping`是否返回PONG
-
防火墙阻止 - 检查服务器安全组或iptables设置
-
密码错误 - 确认auth密码正确
-
连接数超限 - 检查Redis的maxclients配置
Q2: 如何选择phpredis还是Predis?
| 特性 | phpredis | Predis |
|------|----------|--------|
| 性能 | 更快(C扩展) | 稍慢(纯PHP) |
| 安装 | 需要编译 | Composer即可 |
| 功能 | 完整 | 完整 |
| 适用场景 | 生产环境 | 开发/测试环境 |
Q3: 大量数据操作导致内存不足?
-
使用SCAN代替KEYS
-
分批处理大数据量
-
设置合理的过期时间
-
监控Redis内存使用情况
十四、总结
本文详细介绍了PHP操作Redis的各类命令,包括:
-
**字符串** - 最基础的数据类型,适合缓存、计数器等
-
**哈希** - 存储对象,适合用户信息等结构化数据
-
**列表** - 队列、栈的实现,适合消息队列
-
**集合** - 去重、关系运算,适合标签系统
-
**有序集合** - 带权重的集合,适合排行榜
-
**键操作** - 过期、查询、删除等管理操作
-
**事务** - 保证命令原子性执行
-
**发布订阅** - 消息推送机制
-
**管道** - 批量操作提升性能
掌握这些命令,可以应对大多数Redis应用场景。建议结合实际业务需求选择合适的数据类型。
十五、相关链接
-
Redis官方文档\](https://redis.io/documentation)
-
Predis GitHub\](https://github.com/predis/predis)
**标签:** PHP、Redis、缓存、数据库、后端开发