Skip to content

Commit 837e443

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 ebb3541 commit 837e443

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
@@ -212,6 +212,8 @@ PHP_METHOD(Redis, isConnected);
212212
PHP_METHOD(Redis, getPersistentID);
213213
PHP_METHOD(Redis, getAuth);
214214

215+
PHP_METHOD(Redis, command);
216+
215217
#ifdef PHP_WIN32
216218
#define PHP_REDIS_API __declspec(dllexport)
217219
#else

redis.c

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

279+
/* Send a raw command and read raw results */
280+
PHP_ME(Redis, command, NULL, ZEND_ACC_PUBLIC)
281+
279282
/* introspection */
280283
PHP_ME(Redis, getHost, NULL, ZEND_ACC_PUBLIC)
281284
PHP_ME(Redis, getPort, NULL, ZEND_ACC_PUBLIC)
@@ -6177,6 +6180,49 @@ PHP_METHOD(Redis, slowlog) {
61776180
REDIS_PROCESS_RESPONSE(redis_read_variant_reply);
61786181
}
61796182

6183+
/* {{{ proto Redis::command(string cmd, arg, arg, arg, ...) }}} */
6184+
PHP_METHOD(Redis, command) {
6185+
zval **z_args;
6186+
RedisSock *redis_sock;
6187+
int argc = ZEND_NUM_ARGS(), i;
6188+
smart_str cmd = {0};
6189+
6190+
/* We need at least one argument */
6191+
z_args = emalloc(argc * sizeof(zval*));
6192+
if (argc < 1 || zend_get_parameters_array(ht, argc, z_args) == FAILURE) {
6193+
efree(z_args);
6194+
RETURN_FALSE;
6195+
}
6196+
6197+
if (redis_sock_get(getThis(), &redis_sock TSRMLS_CC, 0) < 0) {
6198+
efree(z_args);
6199+
RETURN_FALSE;
6200+
}
6201+
6202+
/* Initialize the command we'll send */
6203+
convert_to_string(z_args[0]);
6204+
redis_cmd_init_sstr(&cmd,argc-1,Z_STRVAL_P(z_args[0]),Z_STRLEN_P(z_args[0]));
6205+
6206+
/* Iterate over the remainder of our arguments, appending */
6207+
for (i = 1; i < argc; i++) {
6208+
convert_to_string(z_args[i]);
6209+
redis_cmd_append_sstr(&cmd, Z_STRVAL_P(z_args[i]), Z_STRLEN_P(z_args[i]));
6210+
}
6211+
6212+
efree(z_args);
6213+
6214+
/* Kick off our request and read response or enqueue handler */
6215+
REDIS_PROCESS_REQUEST(redis_sock, cmd.c, cmd.len);
6216+
IF_ATOMIC() {
6217+
if (redis_read_variant_reply(INTERNAL_FUNCTION_PARAM_PASSTHRU,
6218+
redis_sock, NULL) < 0)
6219+
{
6220+
RETURN_FALSE;
6221+
}
6222+
}
6223+
REDIS_PROCESS_RESPONSE(redis_read_variant_reply);
6224+
}
6225+
61806226
/* {{{ proto Redis::wait(int num_slaves, int ms) }}}
61816227
*/
61826228
PHP_METHOD(Redis, wait) {

0 commit comments

Comments
 (0)