diff --git a/redis.c b/redis.c index 8499d33eff..017e60ee04 100644 --- a/redis.c +++ b/redis.c @@ -2663,54 +2663,43 @@ PHP_METHOD(Redis, setOption) /* {{{ proto boolean Redis::config(string op, string key [, mixed value]) */ PHP_METHOD(Redis, config) { - zval *object; + zend_string *op, *key = NULL, *val = NULL; + FailableResultCallback cb; RedisSock *redis_sock; - char *key = NULL, *val = NULL, *cmd, *op = NULL; - size_t key_len, val_len, op_len; - enum {CFG_GET, CFG_SET} mode; + zval *object; int cmd_len; + char *cmd; - if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), - "Oss|s", &object, redis_ce, &op, &op_len, - &key, &key_len, &val, &val_len) == FAILURE) + if (zend_parse_method_parameters(ZEND_NUM_ARGS(), getThis(), "OS|SS", &object, + redis_ce, &op, &key, &val) == FAILURE) { RETURN_FALSE; } - /* op must be GET or SET */ - if(strncasecmp(op, "GET", 3) == 0) { - mode = CFG_GET; - } else if(strncasecmp(op, "SET", 3) == 0) { - mode = CFG_SET; - } else { - RETURN_FALSE; - } - if ((redis_sock = redis_sock_get(object, 0)) == NULL) { RETURN_FALSE; } - if (mode == CFG_GET && val == NULL) { - cmd_len = REDIS_SPPRINTF(&cmd, "CONFIG", "ss", op, op_len, key, key_len); - - REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len) - if (IS_ATOMIC(redis_sock)) { - redis_mbulk_reply_zipped_raw(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); - } - REDIS_PROCESS_RESPONSE(redis_mbulk_reply_zipped_raw); - - } else if(mode == CFG_SET && val != NULL) { - cmd_len = REDIS_SPPRINTF(&cmd, "CONFIG", "sss", op, op_len, key, key_len, val, val_len); - - REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len) - if (IS_ATOMIC(redis_sock)) { - redis_boolean_response( - INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); - } - REDIS_PROCESS_RESPONSE(redis_boolean_response); + if (zend_string_equals_literal_ci(op, "GET") && key != NULL) { + cmd_len = REDIS_SPPRINTF(&cmd, "CONFIG", "SS", op, key); + cb = redis_mbulk_reply_zipped_raw; + } else if (zend_string_equals_literal_ci(op, "RESETSTAT")) { + cmd_len = REDIS_SPPRINTF(&cmd, "CONFIG", "s", ZEND_STRL("RESETSTAT")); + cb = redis_boolean_response; + } else if (zend_string_equals_literal_ci(op, "SET") && key != NULL && val != NULL) { + cmd_len = REDIS_SPPRINTF(&cmd, "CONFIG", "SSS", op, key, val); + cb = redis_boolean_response; } else { RETURN_FALSE; } + + REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len) + if (IS_ATOMIC(redis_sock)) { + cb(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, NULL); + } + REDIS_PROCESS_RESPONSE(redis_boolean_response); + + return; } /* }}} */ diff --git a/redis.stub.php b/redis.stub.php index ddb551681f..be56508d36 100644 --- a/redis.stub.php +++ b/redis.stub.php @@ -70,7 +70,7 @@ public function close(): bool; public function command(string $opt = null, string|array $arg): mixed; - public function config(string $operation, string $key, mixed $value = null): mixed; + public function config(string $operation, ?string $key = NULL, mixed $value = null): mixed; public function connect(string $host, int $port = 6379, float $timeout = 0, string $persistent_id = null, int $retry_interval = 0, float $read_timeout = 0, array $context = null): bool; diff --git a/redis_arginfo.h b/redis_arginfo.h index e5990f4ee2..66176b346d 100644 --- a/redis_arginfo.h +++ b/redis_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2c5f558917526d1a034a45b63bf7890bd8cb49e5 */ + * Stub hash: 122b5ca534302a09a4f072106d097f2831ba6f22 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, options, IS_ARRAY, 0, "null") @@ -106,9 +106,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_command, 0, 2, IS_MI ZEND_ARG_TYPE_MASK(0, arg, MAY_BE_STRING|MAY_BE_ARRAY, NULL) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_config, 0, 2, IS_MIXED, 0) +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Redis_config, 0, 1, IS_MIXED, 0) ZEND_ARG_TYPE_INFO(0, operation, IS_STRING, 0) - ZEND_ARG_TYPE_INFO(0, key, IS_STRING, 0) + ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, key, IS_STRING, 1, "NULL") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, value, IS_MIXED, 0, "null") ZEND_END_ARG_INFO() diff --git a/redis_cluster_arginfo.h b/redis_cluster_arginfo.h index ca606b3c53..842cd4a207 100644 --- a/redis_cluster_arginfo.h +++ b/redis_cluster_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7ff59229ef9ab94d3bb918d666610b70a5676030 */ + * Stub hash: 97fe79bf371074b77d22e1e820903fb2103d10c9 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_TYPE_INFO(0, name, IS_STRING, 1) diff --git a/redis_cluster_legacy_arginfo.h b/redis_cluster_legacy_arginfo.h index 63ebcd7372..3cc0618de2 100644 --- a/redis_cluster_legacy_arginfo.h +++ b/redis_cluster_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 7ff59229ef9ab94d3bb918d666610b70a5676030 */ + * Stub hash: 97fe79bf371074b77d22e1e820903fb2103d10c9 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_RedisCluster___construct, 0, 0, 1) ZEND_ARG_INFO(0, name) diff --git a/redis_legacy_arginfo.h b/redis_legacy_arginfo.h index ebd87a7d87..1d7673e67d 100644 --- a/redis_legacy_arginfo.h +++ b/redis_legacy_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 2c5f558917526d1a034a45b63bf7890bd8cb49e5 */ + * Stub hash: 122b5ca534302a09a4f072106d097f2831ba6f22 */ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis___construct, 0, 0, 0) ZEND_ARG_INFO(0, options) @@ -97,7 +97,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_command, 0, 0, 2) ZEND_ARG_INFO(0, arg) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_config, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Redis_config, 0, 0, 1) ZEND_ARG_INFO(0, operation) ZEND_ARG_INFO(0, key) ZEND_ARG_INFO(0, value) diff --git a/tests/RedisClusterTest.php b/tests/RedisClusterTest.php index 908e1e58d7..132c3744f3 100644 --- a/tests/RedisClusterTest.php +++ b/tests/RedisClusterTest.php @@ -64,6 +64,7 @@ public function testCopy() { return $this->marktestSkipped(); } public function testGeoSearch() { return $this->marktestSkipped(); } public function testGeoSearchStore() { return $this->marktestSkipped(); } public function testHRandField() { return $this->marktestSkipped(); } + public function testConfig() { return $this->markTestSkipped(); } /* Session locking feature is currently not supported in in context of Redis Cluster. The biggest issue for this is the distribution nature of Redis cluster */ diff --git a/tests/RedisTest.php b/tests/RedisTest.php index c5a87d1546..6c04c9d0d8 100644 --- a/tests/RedisTest.php +++ b/tests/RedisTest.php @@ -5342,6 +5342,31 @@ public function testNestedNullArray() { $this->redis->setOption(Redis::OPT_NULL_MULTIBULK_AS_NULL, false); } + public function testConfig() { + /* GET */ + $cfg = $this->redis->config('GET', 'timeout'); + $this->assertTrue(is_array($cfg) && isset($cfg['timeout'])); + $sec = $cfg['timeout']; + + /* SET */ + foreach ([$sec + 30, $sec] as $val) { + $this->assertTrue($this->redis->config('SET', 'timeout', $val)); + $cfg = $this->redis->config('GET', 'timeout'); + $this->assertTrue(isset($cfg['timeout']) && $cfg['timeout'] == $val); + } + + /* RESETSTAT */ + $c1 = count($this->redis->info('commandstats')); + $this->assertTrue($this->redis->config('resetstat')); + $this->assertTrue(count($this->redis->info('commandstats')) < $c1); + + /* Ensure invalid calls are handled by PhpRedis */ + foreach (['notacommand', 'get', 'set'] as $cmd) { + $this->assertFalse($this->redis->config($cmd)); + } + $this->assertFalse($this->redis->config('set', 'foo')); + } + public function testReconnectSelect() { $key = 'reconnect-select'; $value = 'Has been set!';