源码函数所在文件
为了避免代码影响阅读,以及代码顺序不符合个人的读码习惯,就不贴代码了,都可以通过函数名在下面几个c文件中找到
- redis.c
- library.c
- common.h
几个核心函数
-
redis_connect:用于创建redis对象并建立sock连接。第一个参数INTERNAL_FUNCTION_PARAM_PASSTHRU是宏定义,用来获取函数传入的参数,第二个参数persistent用于区分是否长链接。
-
redis_sock_get:获取sock,检活,第一个参数如果为空的sock对象,则代表用新的连接,并且不需要检活;如果为当前sock对象(getThis函数获取),则需要在hash符号表里查找是否有旧的sock对象。
-
redis_sock_get_instance:根据redis实例的id,返回redis实例中的sock
-
redis_sock_server_open:用于判断socket活跃状态,如果连接已断开调用redis_sock_connect重新连接。
-
redis_sock_create:为redis实例对象创建新的sock连接,申请空间,存储到zend全局空间中
-
redis_sock_disconnect:释放sock连接,如果是长链接从连接池中获取释放,短连接直接释放
-
redis_sock_get_connection_pool:从连接池中获取连接
-
php_stream_pclose:关闭长链接
-
php_stream_close:关闭短连接
-
redis_free_socket:释放sock占用的zend全局空间
几个核心宏定义
-
PHPREDIS_GET_OBJECT:获取redis实例
-
REDIS_THROW_EXCEPTION:抛出异常
-
INTERNAL_FUNCTION_PARAM_PASSTHRU获取参数
pconnect长链接逻辑
调用redis_connect创建长链接经历下面几个步骤(参数persistent为1)
- 初始化变量和参数
- 条件编译,检测ZTS宏定义,将persistent改为0(我猜是在某些环境下不允许长链接)
-
调用zend_parse_method_parameters获取参数,获取失败则返回错误
-
如果是短连接,persistent_id(长链接id)定义为NULL,这里由于是长链接,跳过
-
检测timeout、read_timeout、retry_interval、port
-
调用PHPREDIS_GET_OBJECT宏定义redis对象
-
如果该对象的sock已经被创建则调用redis_sock_disconnect断开sock连接,并调用redis_free_socket释放sock(我认为应该是怕多个并发请求创建重复链接)
-
redis_sock_create创建新的sock持久化连接
-
为了保险,调用redis_sock_server_open检查连接状态,如果连接失败调用redis_free_socket释放sock,并返回错误
-
返回成功
connect短连接逻辑
和上面创建长链接步骤一致,只不过persistent参数为0
redis命令操作
-
REDIS_PROCESS_CMD进入执行redis命令
-
调用redis_sock_get获取当前连接,第一个参数用getThis()函数获取当前redis对象,参数no_throw传0代表redis_sock_get_instance不跳过异常抛出
-
调用redis_sock_get_instance获取redis实例中的sock连接
-
调用redis_sock_server_open检测连接状态,断开会自动重连
-
返回活跃的redis_sock连接
-
用前面返回的sock连接执行redis命令
-
返回命令结果