php redis->close() 之后为什么还能使用 $redis->get('key') 获取数据?

新手上路,请多包涵

$redis = new Redis();
$redis->connect('127.0.0.1',6379);
$redis->set('test','check');
$redis->close();
var_dump($redis->get('test')); ## 这里依然能打印没有报错
exit();

阅读 6.2k
2 个回答

因为 $redis->get() 的时候自动重新连接了。

用 strace 跟踪执行:

# 第一次连接
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("10.217.0.226")}, 16) = -1 EINPROGRESS (Operation now in progress)
getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(4, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
# 发送 set test check
sendto(4, "*3\r\n$3\r\nSET\r\n$4\r\ntest\r\n$5\r\ncheck"..., 34, MSG_DONTWAIT, NULL, 0) = 34
recvfrom(4, "+", 1, MSG_PEEK, NULL, NULL) = 1
recvfrom(4, "+OK\r\n", 8192, MSG_DONTWAIT, NULL, NULL) = 5
# 关闭连接
close(4)                                = 0
# 重新连接!!!
socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 4
connect(4, {sa_family=AF_INET, sin_port=htons(6379), sin_addr=inet_addr("10.217.0.226")}, 16) = -1 EINPROGRESS (Operation now in progress)
getsockopt(4, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
setsockopt(4, SOL_TCP, TCP_NODELAY, [1], 4) = 0
setsockopt(4, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
# 发送 get test
sendto(4, "*2\r\n$3\r\nGET\r\n$4\r\ntest\r\n", 23, MSG_DONTWAIT, NULL, 0) = 23
recvfrom(4, "$", 1, MSG_PEEK, NULL, NULL) = 1
recvfrom(4, "$5\r\ncheck\r\n", 8192, MSG_DONTWAIT, NULL, NULL) = 11
string(5) "check"

从源码来看,get 方法是通过 REDIS_PROCESS_KW_CMD 实现的,其中的 redis_sock_get 会调用 redis_sock_server_open 打开新连接。

$redis->close()

并没有真正的释放资源,然后关闭链接,只是做了一个标记。在 PHP 的语言特性中 GC ( 垃圾回收)并不重要,反正一个 HTTP 请求周期结束之后会统一回收资源。

可以对比一下下面代码的效果:

gc_enable();//开启 gc 自动回收
$redis = new Redis();  
$redis->connect('127.0.0.1',6379);  
$redis->set('test','check');  
$redis->close();  
gc_collect_cycles();//执行一次回收周期
var_dump($redis->get('test')); ## 这里依然能打印没有报错  
exit();

抱歉我并没有自己验证过效果

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题