Skip to content

Commit ef79232

Browse files
Introspection methods
This commit adds methods to get information about the state of our phpredis object, such as what host/port we are connected to, our timeout, etc... The following methods have been added: getHost() getPort() getDBNum() getTimeout() getReadTimeout() isConnected() getPersistentID() getAuth() In addition, there is a small memory leak fix when a persistent id was specifically passed to connect() (it wasn't beeing freed). Addresses issue phpredis#320
1 parent b2ffb7a commit ef79232

File tree

6 files changed

+261
-0
lines changed

6 files changed

+261
-0
lines changed

README.markdown

+86
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ You can send comments, patches, questions [here on github](https://github.com/ni
2626
* [Pub/sub](#pubsub)
2727
* [Transactions](#transactions)
2828
* [Scripting](#scripting)
29+
* [Introspection](#introspection)
2930

3031
-----
3132

@@ -2958,3 +2959,88 @@ serializing values, and you return something from redis in a LUA script that is
29582959
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
29592960
$redis->_unserialize('a:3:{i:0;i:1;i:1;i:2;i:2;i:3;}'); // Will return Array(1,2,3)
29602961
~~~
2962+
2963+
2964+
2965+
## Introspection
2966+
2967+
### IsConnected
2968+
-----
2969+
_**Description**_: A method to determine if a phpredis object thinks it's connected to a server
2970+
2971+
##### *Parameters*
2972+
None
2973+
2974+
##### *Return value*
2975+
*Boolean* Returns TRUE if phpredis thinks it's connected and FALSE if not
2976+
2977+
### GetHost
2978+
-----
2979+
_**Description**_: Retreive our host or unix socket that we're connected to
2980+
2981+
##### *Parameters*
2982+
None
2983+
2984+
##### *Return value*
2985+
*Mixed* The host or unix socket we're connected to or FALSE if we're not connected
2986+
2987+
2988+
### GetPort
2989+
-----
2990+
_**Description**_: Get the port we're connected to
2991+
2992+
##### *Parameters*
2993+
None
2994+
2995+
##### *Return value*
2996+
*Mixed* Returns the port we're connected to or FALSE if we're not connected
2997+
2998+
### getDBNum
2999+
-----
3000+
_**Description**_: Get the database number phpredis is pointed to
3001+
3002+
##### *Parameters*
3003+
None
3004+
3005+
##### *Return value*
3006+
*Mixed* Returns the database number (LONG) phpredis thinks it's pointing to or FALSE if we're not connected
3007+
3008+
### GetTimeout
3009+
-----
3010+
_**Description**_: Get the (write) timeout in use for phpreids
3011+
3012+
##### *Parameters*
3013+
None
3014+
3015+
##### *Return value*
3016+
*Mixed* The timeout (DOUBLE) specified in our connect call or FALSE if we're not connected
3017+
3018+
### GetReadTimeout
3019+
_**Description**_: Get the read timeout specified to phpredis or FALSE if we're not connected
3020+
3021+
##### *Parameters*
3022+
None
3023+
3024+
##### *Return value*
3025+
*Mixed* Returns the read timeout (which can be set using setOption and Redis::OPT_READ_TIMOUT) or FALSE if we're not connected
3026+
3027+
### GetPersistentID
3028+
-----
3029+
_**Description**_: Gets the persistent ID that phpredis is using
3030+
3031+
##### *Parameters*
3032+
None
3033+
3034+
##### *Return value*
3035+
*Mixed* Returns the persistent id phpredis is using (which will only be set if connected with pconnect), NULL if we're not
3036+
using a persistent ID, and FALSE if we're not connected
3037+
3038+
### GetAuth
3039+
-----
3040+
_**Description**_: Get the password used to authenticate the phpredis connection
3041+
3042+
### *Parameters*
3043+
None
3044+
3045+
### *Return value*
3046+
*Mixed* Returns the password used to authenticate a phpredis session or NULL if none was used, and FALSE if we're not connected

common.h

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ typedef struct {
157157
php_stream *stream;
158158
char *host;
159159
short port;
160+
char *auth;
160161
double timeout;
161162
double read_timeout;
162163
int failed;

library.c

+6
Original file line numberDiff line numberDiff line change
@@ -1283,6 +1283,12 @@ PHPAPI void redis_free_socket(RedisSock *redis_sock)
12831283
if(redis_sock->err) {
12841284
efree(redis_sock->err);
12851285
}
1286+
if(redis_sock->auth) {
1287+
efree(redis_sock->auth);
1288+
}
1289+
if(redis_sock->persistent_id) {
1290+
efree(redis_sock->persistent_id);
1291+
}
12861292
efree(redis_sock->host);
12871293
efree(redis_sock);
12881294
}

php_redis.h

+9
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,15 @@ PHP_METHOD(Redis, setOption);
181181

182182
PHP_METHOD(Redis, config);
183183

184+
PHP_METHOD(Redis, getHost);
185+
PHP_METHOD(Redis, getPort);
186+
PHP_METHOD(Redis, getDBNum);
187+
PHP_METHOD(Redis, getTimeout);
188+
PHP_METHOD(Redis, getReadTimeout);
189+
PHP_METHOD(Redis, isConnected);
190+
PHP_METHOD(Redis, getPersistentID);
191+
PHP_METHOD(Redis, getAuth);
192+
184193
#ifdef PHP_WIN32
185194
#define PHP_REDIS_API __declspec(dllexport)
186195
#else

redis.c

+152
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,16 @@ static zend_function_entry redis_functions[] = {
235235
/* config */
236236
PHP_ME(Redis, config, NULL, ZEND_ACC_PUBLIC)
237237

238+
/* introspection */
239+
PHP_ME(Redis, getHost, NULL, ZEND_ACC_PUBLIC)
240+
PHP_ME(Redis, getPort, NULL, ZEND_ACC_PUBLIC)
241+
PHP_ME(Redis, getDBNum, NULL, ZEND_ACC_PUBLIC)
242+
PHP_ME(Redis, getTimeout, NULL, ZEND_ACC_PUBLIC)
243+
PHP_ME(Redis, getReadTimeout, NULL, ZEND_ACC_PUBLIC)
244+
PHP_ME(Redis, getPersistentID, NULL, ZEND_ACC_PUBLIC)
245+
PHP_ME(Redis, getAuth, NULL, ZEND_ACC_PUBLIC)
246+
PHP_ME(Redis, isConnected, NULL, ZEND_ACC_PUBLIC)
247+
238248
/* aliases */
239249
PHP_MALIAS(Redis, open, connect, NULL, ZEND_ACC_PUBLIC)
240250
PHP_MALIAS(Redis, popen, pconnect, NULL, ZEND_ACC_PUBLIC)
@@ -384,6 +394,26 @@ PHPAPI int redis_sock_get(zval *id, RedisSock **redis_sock TSRMLS_DC, int no_thr
384394
return Z_LVAL_PP(socket);
385395
}
386396

397+
/**
398+
* redis_sock_get_direct
399+
* Returns our attached RedisSock pointer if we're connected
400+
*/
401+
PHPAPI RedisSock *redis_sock_get_connected(INTERNAL_FUNCTION_PARAMETERS TSRMLS_DC) {
402+
zval *object;
403+
RedisSock *redis_sock;
404+
405+
// If we can't grab our object, or get a socket, or we're not connected, return NULL
406+
if((zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &object, redis_ce) == FAILURE) ||
407+
(redis_sock_get(object, &redis_sock TSRMLS_CC, 1) < 0) || redis_sock->status != REDIS_SOCK_STATUS_CONNECTED)
408+
{
409+
return NULL;
410+
}
411+
412+
// Return our socket
413+
return redis_sock;
414+
}
415+
416+
387417
/**
388418
* PHP_MINIT_FUNCTION
389419
*/
@@ -3289,6 +3319,10 @@ PHP_METHOD(Redis, auth) {
32893319

32903320
cmd_len = redis_cmd_format_static(&cmd, "AUTH", "s", password, password_len);
32913321

3322+
// Free previously stored auth if we have one, and store this password
3323+
if(redis_sock->auth) efree(redis_sock->auth);
3324+
redis_sock->auth = estrndup(password, password_len);
3325+
32923326
REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len);
32933327
IF_ATOMIC() {
32943328
redis_boolean_response(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL);
@@ -6304,5 +6338,123 @@ PHP_METHOD(Redis, time) {
63046338
REDIS_PROCESS_RESPONSE(redis_sock_read_multibulk_reply_raw);
63056339
}
63066340

6341+
/*
6342+
* Introspection stuff
6343+
*/
6344+
6345+
/*
6346+
* {{{ proto Redis::IsConnected
6347+
*/
6348+
PHP_METHOD(Redis, isConnected) {
6349+
RedisSock *redis_sock;
6350+
6351+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6352+
RETURN_TRUE;
6353+
} else {
6354+
RETURN_FALSE;
6355+
}
6356+
}
6357+
6358+
/*
6359+
* {{{ proto Redis::getHost()
6360+
*/
6361+
PHP_METHOD(Redis, getHost) {
6362+
RedisSock *redis_sock;
6363+
6364+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6365+
RETURN_STRING(redis_sock->host, 1);
6366+
} else {
6367+
RETURN_FALSE;
6368+
}
6369+
}
6370+
6371+
/*
6372+
* {{{ proto Redis::getPort()
6373+
*/
6374+
PHP_METHOD(Redis, getPort) {
6375+
RedisSock *redis_sock;
6376+
6377+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6378+
// Return our port
6379+
RETURN_LONG(redis_sock->port);
6380+
} else {
6381+
RETURN_FALSE;
6382+
}
6383+
}
6384+
6385+
/*
6386+
* {{{ proto Redis::getDBNum
6387+
*/
6388+
PHP_METHOD(Redis, getDBNum) {
6389+
RedisSock *redis_sock;
6390+
6391+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6392+
// Return our db number
6393+
RETURN_LONG(redis_sock->dbNumber);
6394+
} else {
6395+
RETURN_FALSE;
6396+
}
6397+
}
6398+
6399+
/*
6400+
* {{{ proto Redis::getTimeout
6401+
*/
6402+
PHP_METHOD(Redis, getTimeout) {
6403+
RedisSock *redis_sock;
6404+
6405+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6406+
RETURN_DOUBLE(redis_sock->timeout);
6407+
} else {
6408+
RETURN_FALSE;
6409+
}
6410+
}
6411+
6412+
/*
6413+
* {{{ proto Redis::getReadTimeout
6414+
*/
6415+
PHP_METHOD(Redis, getReadTimeout) {
6416+
RedisSock *redis_sock;
6417+
6418+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6419+
RETURN_DOUBLE(redis_sock->read_timeout);
6420+
} else {
6421+
RETURN_FALSE;
6422+
}
6423+
}
6424+
6425+
/*
6426+
* {{{ proto Redis::getPersistentID
6427+
*/
6428+
PHP_METHOD(Redis, getPersistentID) {
6429+
RedisSock *redis_sock;
6430+
6431+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6432+
if(redis_sock->persistent_id != NULL) {
6433+
RETURN_STRING(redis_sock->persistent_id, 1);
6434+
} else {
6435+
RETURN_NULL();
6436+
}
6437+
} else {
6438+
RETURN_FALSE;
6439+
}
6440+
}
6441+
6442+
/*
6443+
* {{{ proto Redis::getAuth
6444+
*/
6445+
PHP_METHOD(Redis, getAuth) {
6446+
RedisSock *redis_sock;
6447+
6448+
if((redis_sock = redis_sock_get_connected(INTERNAL_FUNCTION_PARAM_PASSTHRU TSRMLS_CC))) {
6449+
if(redis_sock->auth != NULL) {
6450+
RETURN_STRING(redis_sock->auth, 1);
6451+
} else {
6452+
RETURN_NULL();
6453+
}
6454+
} else {
6455+
RETURN_FALSE;
6456+
}
6457+
}
6458+
63076459
/* vim: set tabstop=4 softtabstop=4 noexpandtab shiftwidth=4: */
63086460

tests/TestRedis.php

+7
Original file line numberDiff line numberDiff line change
@@ -4301,6 +4301,13 @@ public function testReadTimeoutOption() {
43014301
$this->assertEquals(12.3, $this->redis->getOption(Redis::OPT_READ_TIMEOUT));
43024302
}
43034303

4304+
public function testIntrospection() {
4305+
// Simple introspection tests
4306+
$this->assertTrue($this->redis->getHost() === self::HOST);
4307+
$this->assertTrue($this->redis->getPort() === self::PORT);
4308+
$this->assertTrue($this->redis->getAuth() === self::AUTH);
4309+
}
4310+
43044311
}
43054312

43064313
exit(TestSuite::run("Redis_Test"));

0 commit comments

Comments
 (0)