php怎么操作Redis_Redis扩展连接与基本命令使用方法【方法】

14次阅读

redis扩展必须安装并启用才能使用new Redis(),否则报class ‘Redis’ not found;predis是纯php客户端但性能较差;set/get默认序列化导致NULL值歧义;pipeline提升吞吐量,multi保证简单事务,复杂场景需lua或应用层锁。

php怎么操作Redis_Redis扩展连接与基本命令使用方法【方法】

Redis 扩展是否已安装并启用

PHP 操作 Redis 前,必须确认 redis 扩展已编译进 PHP 或通过 extension=redis.solinux/macOS)或 extension=php_redis.dllwindows)启用。仅装了 phpredis 包但没启用扩展,调用 new Redis() 会直接报错 Class 'Redis' not found

验证方式很简单:

php -m | grep redis

或者在 Web 环境中运行:

  • 返回 true 才能继续;返回 false 就得先配扩展,不是装 composer require predis/predis 就能替代的
  • predis 是纯 PHP 客户端,不依赖扩展,但性能和连接复用能力弱于原生 redis 扩展
  • PHP 8.0+ 用户注意:旧版 phpredis(5.3.7+ 版本

new Redis() 连接时的超时与重试控制

默认 new Redis() 不带参数时不会自动连接,首次调用命令(如 set)才触发连接,且默认超时是 0(无限等待),线上环境极易卡死。必须显式调用 connect() 并设好超时。

立即学习PHP免费学习笔记(深入)”;

  • connect($host, $port, $timeout, $retry_interval, $read_timeout) 中,$timeout 是连接建立超时(秒),$read_timeout 是读响应超时(秒),两者都应设为 1.0 或更小
  • $retry_interval 在连接失败后重试前等待毫秒数,设为 100 可避免密集轮询
  • 不要用 pconnect() 在 CLI 脚本里——它不会真正复用连接,反而可能残留 socket 导致 Too many open files
connect('127.0.0.1', 6379, 1.0, 100, 1.0); } catch (RedisException $e) {     // 注意:RedisException 不是 RuntimeException,需单独捕获     error_log('Redis connect failed: ' . $e->getMessage());     exit(1); } ?>

set / get 的序列化行为与 null 值陷阱

set() 默认对非字符串值做 serialize()get() 会自动 unserialize()。这看似方便,实则埋下隐患:

  • null 时,get() 返回 false(不是 null),且无法区分“键不存在”和“存了 null”
  • 开启 redis.serializer = phpphp.ini)会影响所有实例,不推荐;应在代码里统一用 setex() + json_encode() 控制格式
  • 如果只存字符串,显式转成字符串再 set,避免意外序列化:$redis->set('key', (String)$value)
set('user:id:123', json_encode(['name' => 'Alice', 'age' => 30])); $data = json_decode($redis->get('user:id:123'), true); // 比直接 set(array) + get() 更可控、无反序列化风险 ?>

pipeline 和 multi 的适用边界

批量操作别盲目上 multi(Redis::PIPELINE)。它只是把命令攒起来发一次,不保证原子性;而 multi(Redis::MULTI) 才是事务,但 Redis 的事务不支持回滚,出错只报错不中断。

  • 纯粹提升吞吐量(比如批量写日志)、无需一致性校验 → 用 pipeline
  • 需要多个 key 同时成功/失败(如扣库存+写订单),且逻辑简单 → 用 multi + exec,但得自己检查 exec 返回值是否全为非 null
  • watch() 配合 multi 可实现乐观锁,但 watch 的 key 被改就会使 exec 返回 false,这点常被忽略

真正难处理的是跨库、跨实例、含条件判断的复合操作——这时候就得退回到应用层加锁或用 Lua 脚本,而不是硬塞进 pipeline。

text=ZqhQzanResources