本文目录导读:

我来详细介绍在PHP项目中操作Redis的方法:
安装Redis扩展
使用PECL安装
pecl install redis
编译安装
# 下载扩展 wget https://github.com/phpredis/phpredis/archive/develop.zip unzip develop.zip cd phpredis-develop # 编译安装 phpize ./configure make && make install # 在php.ini中添加 extension=redis.so
Composer安装(推荐)
{
"require": {
"predis/predis": "^2.0"
}
}
连接Redis
基本连接
<?php
// 使用phpredis扩展(面向对象方式)
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->auth('password'); // 如果有密码
// 使用Predis库
require 'vendor/autoload.php';
$client = new Predis\Client([
'scheme' => 'tcp',
'host' => '127.0.0.1',
'port' => 6379,
'password' => 'password' // 可选
]);
连接池配置
// 使用长连接
$redis->pconnect('127.0.0.1', 6379);
// 设置连接池参数
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$redis->setOption(Redis::OPT_PREFIX, 'myapp:');
基本操作
字符串操作
// 设置值
$redis->set('key', 'value');
$redis->setex('key_expire', 3600, 'value'); // 设置过期时间(秒)
$redis->setnx('key', 'value'); // 仅当key不存在时设置
// 获取值
$value = $redis->get('key');
// 批量操作
$redis->mset(['key1' => 'val1', 'key2' => 'val2']);
$values = $redis->mget(['key1', 'key2']);
// 递增递减
$redis->incr('counter');
$redis->incrBy('counter', 10);
$redis->decr('counter');
哈希操作
// 设置哈希字段
$redis->hSet('user:1', 'name', '张三');
$redis->hMSet('user:1', [
'name' => '张三',
'age' => 25,
'city' => '北京'
]);
// 获取哈希字段
$name = $redis->hGet('user:1', 'name');
$user = $redis->hGetAll('user:1');
$fields = $redis->hMGet('user:1', ['name', 'age']);
// 检查字段是否存在
$exists = $redis->hExists('user:1', 'name');
// 删除字段
$redis->hDel('user:1', 'age');
// 获取所有字段
$keys = $redis->hKeys('user:1');
$values = $redis->hVals('user:1');
列表操作
// 左/右插入
$redis->lPush('tasks', 'task1');
$redis->rPush('tasks', 'task2');
// 左/右弹出
$task = $redis->lPop('tasks');
$task = $redis->rPop('tasks');
// 获取列表长度
$length = $redis->lLen('tasks');
// 获取范围内元素
$tasks = $redis->lRange('tasks', 0, -1);
// 阻塞弹出(带超时)
$task = $redis->blPop(['tasks'], 5); // 等待5秒
集合操作
// 添加元素
$redis->sAdd('users:online', 'user1', 'user2');
// 检查成员
$isMember = $redis->sIsMember('users:online', 'user1');
// 获取所有成员
$members = $redis->sMembers('users:online');
// 集合运算
$redis->sAdd('set1', 'a', 'b', 'c');
$redis->sAdd('set2', 'b', 'c', 'd');
$union = $redis->sUnion('set1', 'set2'); // 并集
$intersect = $redis->sInter('set1', 'set2'); // 交集
$diff = $redis->sDiff('set1', 'set2'); // 差集
有序集合操作
// 添加分数成员
$redis->zAdd('scores', 100, 'Alice');
$redis->zAdd('scores', 90, 'Bob');
// 获取排名
$rank = $redis->zRank('scores', 'Alice'); // 升序
$rank = $redis->zRevRank('scores', 'Alice'); // 降序
// 获取范围内的成员
$top3 = $redis->zRevRange('scores', 0, 2, true);
// 增加分数
$redis->zIncrBy('scores', 10, 'Bob');
// 获取分数
$score = $redis->zScore('scores', 'Bob');
高级功能
事务处理
// 方式一:multi/exec
$redis->multi();
$redis->set('key1', 'value1');
$redis->set('key2', 'value2');
$redis->incr('counter');
$result = $redis->exec(); // 执行事务
// 方式二:discard(取消事务)
$redis->multi();
$redis->set('key1', 'value1');
$redis->discard(); // 取消事务
// 乐观锁(watch)
$redis->watch('stock');
$stock = $redis->get('stock');
if ($stock > 0) {
$redis->multi();
$redis->decr('stock');
$redis->exec();
}
管道操作
// 批量发送命令,提高性能
$redis->pipeline();
$redis->set('key1', 'value1');
$redis->set('key2', 'value2');
$redis->set('key3', 'value3');
$results = $redis->exec();
发布/订阅
// 发布者
$redis->publish('channel', 'message');
// 订阅者(需要单独脚本)
$redis->subscribe(['channel'], function($redis, $channel, $message) {
echo "收到消息: $message\n";
});
Lua脚本
// 原子性脚本执行
$lua = <<<'SCRIPT'
local current = redis.call('GET', KEYS[1])
if not current then
return redis.error_reply('Key not found')
end
if tonumber(current) > tonumber(ARGV[1]) then
return redis.error_reply('Value is too large')
end
return redis.call('INCR', KEYS[1])
SCRIPT;
$result = $redis->eval($lua, ['counter', '10'], 1);
实际应用示例
缓存实现
class CacheService {
private $redis;
private $ttl = 3600; // 默认1小时
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function get($key, $callback = null) {
$value = $this->redis->get($key);
if ($value === false && $callback) {
$value = $callback();
$this->set($key, $value);
}
return $value;
}
public function set($key, $value, $ttl = null) {
$ttl = $ttl ?? $this->ttl;
return $this->redis->setex($key, $ttl, $value);
}
public function delete($key) {
return $this->redis->del($key);
}
public function clear($pattern = '*') {
$keys = $this->redis->keys($pattern);
if (!empty($keys)) {
return $this->redis->del($keys);
}
return 0;
}
}
分布式锁
class RedisLock {
private $redis;
private $lockTime = 10; // 锁超时时间(秒)
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function acquire($key, $requestId) {
$result = $this->redis->set(
"lock:$key",
$requestId,
['NX', 'EX' => $this->lockTime]
);
return $result !== false;
}
public function release($key, $requestId) {
$script = <<<'LUA'
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
LUA;
return $this->redis->eval($script, ["lock:$key", $requestId], 1);
}
}
用户会话管理
class SessionManager {
private $redis;
private $sessionPrefix = 'session:';
private $sessionTimeout = 1800; // 30分钟
public function __construct() {
$this->redis = new Redis();
$this->redis->connect('127.0.0.1', 6379);
}
public function createSession($userId, $data = []) {
$sessionId = bin2hex(random_bytes(32));
$key = $this->sessionPrefix . $sessionId;
$data['user_id'] = $userId;
$data['created_at'] = time();
$this->redis->hMSet($key, $data);
$this->redis->expire($key, $this->sessionTimeout);
return $sessionId;
}
public function getSession($sessionId) {
$key = $this->sessionPrefix . $sessionId;
$data = $this->redis->hGetAll($key);
if (!empty($data)) {
$this->redis->expire($key, $this->sessionTimeout); // 续期
}
return $data;
}
public function destroySession($sessionId) {
return $this->redis->del($this->sessionPrefix . $sessionId);
}
}
性能优化建议
// 1. 使用长连接
$redis = new Redis();
$redis->pconnect('127.0.0.1', 6379, 2.5); // 2.5秒超时
// 2. 批量操作代替循环
// 不推荐
foreach ($items as $key => $value) {
$redis->set($key, $value);
}
// 推荐
$pipe = $redis->pipeline();
foreach ($items as $key => $value) {
$pipe->set($key, $value);
}
$pipe->exec();
// 3. 使用scan代替keys(大数据量时)
$iterator = null;
while ($keys = $redis->scan($iterator, 'pattern:*')) {
foreach ($keys as $key) {
// 处理key
}
}
// 4. 合理设置序列化
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
错误处理
try {
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$redis->set('test', 'value');
} catch (RedisException $e) {
// 连接失败或操作异常
error_log("Redis error: " . $e->getMessage());
// 重试逻辑
if ($e->getCode() == 0) { // 连接错误
sleep(1);
$redis->connect('127.0.0.1', 6379);
}
} finally {
if (isset($redis)) {
$redis->close();
}
}
这些是PHP操作Redis的核心内容,根据项目需求选择合适的扩展库和实现方式,注意性能优化和错误处理。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播