fuyelk/redis

Redis的常用操作的封装

Maintainers

Package info

github.com/fuyelk/redis

pkg:composer/fuyelk/redis

Transparency log

Statistics

Installs: 154

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

2.0.0 2026-08-30 14:37 UTC

This package is auto-updated.

Last update: 2026-08-30 14:37:47 UTC


README

PHP 原生 Redis 扩展(ext-redis / phpredis)的轻量封装。

不是新客户端,也不替代 \Redis。调用方式与原生接近,在其上补齐业务里反复要写的那一层:前缀隔离、序列化、断线重连、原子锁、按集合批量删除。

未封装的命令仍可通过 __call 转到 phpredis(只给第一个标量参数加前缀)。

composer require fuyelk/redis

需要 PHP >= 7.4ext-redis。2.0 为破坏性升级,从 1.x 迁移见 CHANGELOG.md

解决什么问题

场景 原生 phpredis 本库
一台 Redis 多个项目 键名自己约定,容易撞 自动加 prefix,项目之间数据隔离
set 数组 / 布尔 不能直接存,要自己 serialize 写入自动编码,读取自动还原(不还原为对象)
Redis 闪断 抛异常,业务自己重连 最多重试 3 次(带退避),失败再抛,不把 PHP 卡死
防重复提交 / 回调解锁 自己拼 SETNX + EXPIRE,容易死锁或误删 lock / unlockSET NX EX + token,可跨请求传凭证
按一批逻辑名清缓存 循环 DEL,还要记得加前缀 sAdd + delBySet
列出 / 清空「当前项目」的键 KEYS * 扫全库,生产会堵 keys / delAll / allData 只用 SCAN,且只动当前前缀

本库不写配置文件,不会在 vendor/ 下落盘。请自行单例,避免每个请求 new 一次。生产环境(多机、队列 Worker)必须显式传 prefix

快速开始

$redis = new \fuyelk\redis\Redis([
    'host' => '127.0.0.1',
    'password' => '',
    'prefix' => 'myapp:',   // 生产必须显式传入
]);

$redis->set('name', 'zhangsan');
$redis->get('name', 'default');     // key 不存在时返回默认值
$redis->set('profile', ['age' => 18]); // 数组可直接存取

if ($token = $redis->lock('submit', 10)) {
    // ... 业务 ...
    $redis->unlock('submit');
}

配置

优先级:构造参数 > 环境变量 > 默认值

环境变量 默认
host REDIS_HOST 127.0.0.1
port REDIS_PORT 6379
password REDIS_PASSWORD
db REDIS_DB 0
timeout REDIS_TIMEOUT 3
prefix REDIS_PREFIX md5(getcwd()) 前 8 位 + :
expire (仅构造参数) 0 不过期
persistent (仅构造参数) false

未传 prefix 且未设环境变量时,用当前工作目录生成稳定前缀(同一台机器上不同项目不撞键)。多机部署 cwd 可能不同,不要依赖这个默认值

方法示例

$redis = new \fuyelk\redis\Redis(['prefix' => 'myapp:']);

$redis->set('name', 'zhangsan');
$redis->get('name', 'default');
$redis->setnx('exist', 'yes');
$redis->del('age');

$redis->inc('money', 5);
$redis->dec('money', 5);

// 集合 member 必须是未加库前缀的逻辑名
$redis->sAdd('users', 'user:1', 'user:2');
$redis->delBySet('users');

$redis->keys();      // 当前前缀下的键名(SCAN)
$redis->allData();   // 当前前缀下的 string 数据(hash/list/set 会跳过)
$redis->delAll();    // 只删当前前缀,不会清空整个 Redis

hash / list / set / zset 等未单独封装的命令,用法与 phpredis 相同,例如 $redis->hSet('user', 'name', 'alice')

lock 使用 SET key token NX EX seconds。成功返回 token 字符串(可直接 if ($redis->lock())),失败返回 false

unlock($name, $token = null) 用 Lua:值等于 token 才删除。

  • 同一请求:unlock($name) 即可。
  • 支付回调等另一进程:加锁时把 token 存进业务数据,回调里 unlock($name, $savedToken)
  • 无 token 或 token 不匹配:不解,返回 false。避免迟到回调拆掉别人后来抢到的锁。

锁在 EX 秒后由 Redis 自动释放。不提供无凭证的强制解锁;若坚持按名字强删,可 $redis->del('lock:'.$name),须自行承担误删风险。

delBySet

sAdd('cache_keys', 'page:home') 的 member 是逻辑名,库只会给集合名加 prefix。

delBySet('cache_keys') 会对每个 member 再加一次 prefix 后删除,因此 member 不能已是完整 Redis key。若 member 已带库前缀,会删错键。