Skip to content

Commit 81383b2

Browse files
Support for the "command" command.
This is a simple addition that allows a client to call any given Redis command by sending the command name followed by a list of arguments. This is useful for the cases where there are new commands in Redis that have not yet been specifically implemented in phpredis, or if you want to use phpredis as a pass-through where the commands and arguments are coming from somewhere else (e.g. monitor logs, etc).
1 parent c1f862c commit 81383b2

File tree

2 files changed

+48
-0
lines changed

2 files changed

+48
-0
lines changed

php_redis.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,8 @@ PHP_METHOD(Redis, isConnected);
206206
PHP_METHOD(Redis, getPersistentID);
207207
PHP_METHOD(Redis, getAuth);
208208

209+
PHP_METHOD(Redis, command);
210+
209211
#ifdef PHP_WIN32
210212
#define PHP_REDIS_API __declspec(dllexport)
211213
#else

redis.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,9 @@ static zend_function_entry redis_functions[] = {
270270
/* slowlog */
271271
PHP_ME(Redis, slowlog, NULL, ZEND_ACC_PUBLIC)
272272

273+
/* Send a raw command and read raw results */
274+
PHP_ME(Redis, command, NULL, ZEND_ACC_PUBLIC)
275+
273276
/* introspection */
274277
PHP_ME(Redis, getHost, NULL, ZEND_ACC_PUBLIC)
275278
PHP_ME(Redis, getPort, NULL, ZEND_ACC_PUBLIC)
@@ -6100,6 +6103,49 @@ PHP_METHOD(Redis, slowlog) {
61006103
REDIS_PROCESS_RESPONSE(redis_read_variant_reply);
61016104
}
61026105

6106+
/* {{{ proto Redis::command(string cmd, arg, arg, arg, ...) }}} */
6107+
PHP_METHOD(Redis, command) {
6108+
zval **z_args;
6109+
RedisSock *redis_sock;
6110+
int argc = ZEND_NUM_ARGS(), i;
6111+
smart_str cmd = {0};
6112+
6113+
/* We need at least one argument */
6114+
z_args = emalloc(argc * sizeof(zval*));
6115+
if (argc < 1 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
6116+
efree(z_args);
6117+
RETURN_FALSE;
6118+
}
6119+
6120+
if (redis_sock_get(getThis(), &redis_sock TSRMLS_CC, 0) < 0) {
6121+
efree(z_args);
6122+
RETURN_FALSE;
6123+
}
6124+
6125+
/* Initialize the command we'll send */
6126+
convert_to_string(z_args[0]);
6127+
redis_cmd_init_sstr(&cmd,argc-1,Z_STRVAL_P(z_args[0]),Z_STRLEN_P(z_args[0]));
6128+
6129+
/* Iterate over the remainder of our arguments, appending */
6130+
for (i = 1; i < argc; i++) {
6131+
convert_to_string(z_args[i]);
6132+
redis_cmd_append_sstr(&cmd, Z_STRVAL_P(z_args[i]), Z_STRLEN_P(z_args[i]));
6133+
}
6134+
6135+
efree(z_args);
6136+
6137+
/* Kick off our request and read response or enqueue handler */
6138+
REDIS_PROCESS_REQUEST(redis_sock, cmd.c, cmd.len);
6139+
IF_ATOMIC() {
6140+
if (redis_read_variant_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
6141+
redis_sock, NULL) < 0)
6142+
{
6143+
RETURN_FALSE;
6144+
}
6145+
}
6146+
REDIS_PROCESS_RESPONSE(redis_read_variant_reply);
6147+
}
6148+
61036149
/* {{{ proto Redis::wait(int num_slaves, int ms) }}}
61046150
*/
61056151
PHP_METHOD(Redis, wait) {

0 commit comments

Comments
 (0)