1 #include "php.h" 2 #include "php_ini.h" 3 4 #ifndef REDIS_COMMON_H 5 #define REDIS_COMMON_H 6 7 #define PHPREDIS_NOTUSED(v) ((void)v) 8 9 #include "zend_llist.h" 10 #include <ext/standard/php_var.h> 11 #include <ext/standard/php_math.h> 12 #include <zend_smart_str.h> 13 #include <ext/standard/php_smart_string.h> 14 15 #define PHPREDIS_GET_OBJECT(class_entry, o) (class_entry *)((char *)o - XtOffsetOf(class_entry, std)) 16 #define PHPREDIS_ZVAL_GET_OBJECT(class_entry, z) PHPREDIS_GET_OBJECT(class_entry, Z_OBJ_P(z)) 17 18 /* NULL check so Eclipse doesn't go crazy */ 19 #ifndef NULL 20 #define NULL ((void *) 0) 21 #endif 22 23 #include "backoff.h" 24 25 typedef enum { 26 REDIS_SOCK_STATUS_FAILED = -1, 27 REDIS_SOCK_STATUS_DISCONNECTED, 28 REDIS_SOCK_STATUS_CONNECTED, 29 REDIS_SOCK_STATUS_READY 30 } redis_sock_status; 31 32 #define _NL "\r\n" 33 34 /* properties */ 35 #define REDIS_NOT_FOUND 0 36 #define REDIS_STRING 1 37 #define REDIS_SET 2 38 #define REDIS_LIST 3 39 #define REDIS_ZSET 4 40 #define REDIS_HASH 5 41 #define REDIS_STREAM 6 42 43 #ifdef PHP_WIN32 44 #define PHP_REDIS_API __declspec(dllexport) 45 #define phpredis_atoi64(p) _atoi64((p)) 46 #else 47 #define PHP_REDIS_API 48 #define phpredis_atoi64(p) atoll((p)) 49 #endif 50 51 /* reply types */ 52 typedef enum _REDIS_REPLY_TYPE { 53 TYPE_EOF = -1, 54 TYPE_LINE = '+', 55 TYPE_INT = ':', 56 TYPE_ERR = '-', 57 TYPE_BULK = '$', 58 TYPE_MULTIBULK = '*' 59 } REDIS_REPLY_TYPE; 60 61 /* SCAN variants */ 62 typedef enum _REDIS_SCAN_TYPE { 63 TYPE_SCAN, 64 TYPE_SSCAN, 65 TYPE_HSCAN, 66 TYPE_ZSCAN 67 } REDIS_SCAN_TYPE; 68 69 /* PUBSUB subcommands */ 70 typedef enum _PUBSUB_TYPE { 71 PUBSUB_CHANNELS, 72 PUBSUB_NUMSUB, 73 PUBSUB_NUMPAT 74 } PUBSUB_TYPE; 75 76 /* options */ 77 #define REDIS_OPT_SERIALIZER 1 78 #define REDIS_OPT_PREFIX 2 79 #define REDIS_OPT_READ_TIMEOUT 3 80 #define REDIS_OPT_SCAN 4 81 #define REDIS_OPT_FAILOVER 5 82 #define REDIS_OPT_TCP_KEEPALIVE 6 83 #define REDIS_OPT_COMPRESSION 7 84 #define REDIS_OPT_REPLY_LITERAL 8 85 #define REDIS_OPT_COMPRESSION_LEVEL 9 86 #define REDIS_OPT_NULL_MBULK_AS_NULL 10 87 #define REDIS_OPT_MAX_RETRIES 11 88 #define REDIS_OPT_BACKOFF_ALGORITHM 12 89 #define REDIS_OPT_BACKOFF_BASE 13 90 #define REDIS_OPT_BACKOFF_CAP 14 91 92 /* cluster options */ 93 #define REDIS_FAILOVER_NONE 0 94 #define REDIS_FAILOVER_ERROR 1 95 #define REDIS_FAILOVER_DISTRIBUTE 2 96 #define REDIS_FAILOVER_DISTRIBUTE_SLAVES 3 97 /* serializers */ 98 typedef enum { 99 REDIS_SERIALIZER_NONE, 100 REDIS_SERIALIZER_PHP, 101 REDIS_SERIALIZER_IGBINARY, 102 REDIS_SERIALIZER_MSGPACK, 103 REDIS_SERIALIZER_JSON 104 } redis_serializer; 105 /* compression */ 106 #define REDIS_COMPRESSION_NONE 0 107 #define REDIS_COMPRESSION_LZF 1 108 #define REDIS_COMPRESSION_ZSTD 2 109 #define REDIS_COMPRESSION_LZ4 3 110 111 /* SCAN options */ 112 #define REDIS_SCAN_NORETRY 0 113 #define REDIS_SCAN_RETRY 1 114 #define REDIS_SCAN_PREFIX 2 115 #define REDIS_SCAN_NOPREFIX 3 116 117 /* BACKOFF_ALGORITHM options */ 118 #define REDIS_BACKOFF_ALGORITHMS 7 119 #define REDIS_BACKOFF_ALGORITHM_DEFAULT 0 120 #define REDIS_BACKOFF_ALGORITHM_DECORRELATED_JITTER 1 121 #define REDIS_BACKOFF_ALGORITHM_FULL_JITTER 2 122 #define REDIS_BACKOFF_ALGORITHM_EQUAL_JITTER 3 123 #define REDIS_BACKOFF_ALGORITHM_EXPONENTIAL 4 124 #define REDIS_BACKOFF_ALGORITHM_UNIFORM 5 125 #define REDIS_BACKOFF_ALGORITHM_CONSTANT 6 126 127 /* GETBIT/SETBIT offset range limits */ 128 #define BITOP_MIN_OFFSET 0 129 #define BITOP_MAX_OFFSET 4294967295U 130 131 /* Transaction modes */ 132 #define ATOMIC 0 133 #define MULTI 1 134 #define PIPELINE 2 135 136 #define PHPREDIS_DEBUG_LOGGING 0 137 138 #if PHPREDIS_DEBUG_LOGGING == 1 139 #define redisDbgFmt(fmt, ...) \ 140 php_printf("%s:%d:%s(): " fmt "\n", __FILE__, __LINE__, __func__, __VA_ARGS__) 141 #define redisDbgStr(str) phpredisDebugFmt("%s", str) 142 #else 143 #define redisDbgFmt(fmt, ...) ((void)0) 144 #define redisDbgStr(str) ((void)0) 145 #endif 146 147 #define IS_ATOMIC(redis_sock) (redis_sock->mode == ATOMIC) 148 #define IS_MULTI(redis_sock) (redis_sock->mode & MULTI) 149 #define IS_PIPELINE(redis_sock) (redis_sock->mode & PIPELINE) 150 151 #define PIPELINE_ENQUEUE_COMMAND(cmd, cmd_len) do { \ 152 if (redis_sock->pipeline_cmd == NULL) { \ 153 redis_sock->pipeline_cmd = zend_string_init(cmd, cmd_len, 0); \ 154 } else { \ 155 size_t pipeline_len = ZSTR_LEN(redis_sock->pipeline_cmd); \ 156 redis_sock->pipeline_cmd = zend_string_realloc(redis_sock->pipeline_cmd, pipeline_len + cmd_len, 0); \ 157 memcpy(&ZSTR_VAL(redis_sock->pipeline_cmd)[pipeline_len], cmd, cmd_len); \ 158 } \ 159 } while (0) 160 161 #define SOCKET_WRITE_COMMAND(redis_sock, cmd, cmd_len) \ 162 if(redis_sock_write(redis_sock, cmd, cmd_len) < 0) { \ 163 efree(cmd); \ 164 RETURN_FALSE; \ 165 } 166 167 #define REDIS_SAVE_CALLBACK(callback, closure_context) do { \ 168 fold_item *fi = malloc(sizeof(fold_item)); \ 169 fi->fun = callback; \ 170 fi->ctx = closure_context; \ 171 fi->next = NULL; \ 172 if (redis_sock->current) { \ 173 redis_sock->current->next = fi; \ 174 } \ 175 redis_sock->current = fi; \ 176 if (NULL == redis_sock->head) { \ 177 redis_sock->head = redis_sock->current; \ 178 } \ 179 } while (0) 180 181 #define REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len) \ 182 if (IS_PIPELINE(redis_sock)) { \ 183 PIPELINE_ENQUEUE_COMMAND(cmd, cmd_len); \ 184 } else { \ 185 SOCKET_WRITE_COMMAND(redis_sock, cmd, cmd_len); \ 186 } \ 187 efree(cmd); 188 189 #define REDIS_PROCESS_RESPONSE_CLOSURE(function, closure_context) \ 190 if (!IS_PIPELINE(redis_sock)) { \ 191 if (redis_response_enqueued(redis_sock) != SUCCESS) { \ 192 RETURN_FALSE; \ 193 } \ 194 } \ 195 REDIS_SAVE_CALLBACK(function, closure_context); \ 196 RETURN_ZVAL(getThis(), 1, 0); \ 197 198 #define REDIS_PROCESS_RESPONSE(function) else { \ 199 REDIS_PROCESS_RESPONSE_CLOSURE(function, NULL) \ 200 } 201 202 /* Clear redirection info */ 203 #define REDIS_MOVED_CLEAR(redis_sock) \ 204 redis_sock->redir_slot = 0; \ 205 redis_sock->redir_port = 0; \ 206 redis_sock->redir_type = MOVED_NONE; \ 207 208 /* Process a command assuming our command where our command building 209 * function is redis_<cmdname>_cmd */ 210 #define REDIS_PROCESS_CMD(cmdname, resp_func) \ 211 RedisSock *redis_sock; char *cmd; int cmd_len; void *ctx=NULL; \ 212 if ((redis_sock = redis_sock_get(getThis(), 0)) == NULL || \ 213 redis_##cmdname##_cmd(INTERNAL_FUNCTION_PARAM_PASSTHRU,redis_sock, \ 214 &cmd, &cmd_len, NULL, &ctx)==FAILURE) { \ 215 RETURN_FALSE; \ 216 } \ 217 REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len); \ 218 if (IS_ATOMIC(redis_sock)) { \ 219 resp_func(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, ctx); \ 220 } else { \ 221 REDIS_PROCESS_RESPONSE_CLOSURE(resp_func, ctx) \ 222 } 223 224 /* Process a command but with a specific command building function 225 * and keyword which is passed to us*/ 226 #define REDIS_PROCESS_KW_CMD(kw, cmdfunc, resp_func) \ 227 RedisSock *redis_sock; char *cmd; int cmd_len; void *ctx=NULL; \ 228 if ((redis_sock = redis_sock_get(getThis(), 0)) == NULL || \ 229 cmdfunc(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, kw, &cmd, \ 230 &cmd_len, NULL, &ctx)==FAILURE) { \ 231 RETURN_FALSE; \ 232 } \ 233 REDIS_PROCESS_REQUEST(redis_sock, cmd, cmd_len); \ 234 if (IS_ATOMIC(redis_sock)) { \ 235 resp_func(INTERNAL_FUNCTION_PARAM_PASSTHRU, redis_sock, NULL, ctx); \ 236 } else { \ 237 REDIS_PROCESS_RESPONSE_CLOSURE(resp_func, ctx) \ 238 } 239 240 /* Case sensitive compare against compile-time static string */ 241 #define REDIS_STRCMP_STATIC(s, len, sstr) \ 242 (len == sizeof(sstr) - 1 && !strncmp(s, sstr, len)) 243 244 /* Case insensitive compare against compile-time static string */ 245 #define REDIS_STRICMP_STATIC(s, len, sstr) \ 246 (len == sizeof(sstr) - 1 && !strncasecmp(s, sstr, len)) 247 248 /* Test if a zval is a string and (case insensitive) matches a static string */ 249 #define ZVAL_STRICMP_STATIC(zv, sstr) \ 250 REDIS_STRICMP_STATIC(Z_STRVAL_P(zv), Z_STRLEN_P(zv), sstr) 251 252 /* Case insensitive compare of a zend_string to a static string */ 253 #define ZSTR_STRICMP_STATIC(zs, sstr) \ 254 REDIS_STRICMP_STATIC(ZSTR_VAL(zs), ZSTR_LEN(zs), sstr) 255 256 /* Extended SET argument detection */ 257 #define ZSTR_IS_EX_ARG(zs) ZSTR_STRICMP_STATIC(zs, "EX") 258 #define ZSTR_IS_PX_ARG(zs) ZSTR_STRICMP_STATIC(zs, "PX") 259 #define ZSTR_IS_NX_ARG(zs) ZSTR_STRICMP_STATIC(zs, "NX") 260 #define ZSTR_IS_XX_ARG(zs) ZSTR_STRICMP_STATIC(zs, "XX") 261 262 #define ZVAL_IS_NX_XX_ARG(zv) (ZVAL_STRICMP_STATIC(zv, "NX") || ZVAL_STRICMP_STATIC(zv, "XX")) 263 #define ZSTR_IS_EX_PX_ARG(a) (ZSTR_IS_EX_ARG(a) || ZSTR_IS_PX_ARG(a)) 264 265 /* Given a string and length, validate a zRangeByLex argument. The semantics 266 * here are that the argument must start with '(' or '[' or be just the char 267 * '+' or '-' */ 268 #define IS_LEX_ARG(s,l) \ 269 (l>0 && (*s=='(' || *s=='[' || (l==1 && (*s=='+' || *s=='-')))) 270 271 #define REDIS_ENABLE_MODE(redis_sock, m) (redis_sock->mode |= m) 272 #define REDIS_DISABLE_MODE(redis_sock, m) (redis_sock->mode &= ~m) 273 274 /* HOST_NAME_MAX doesn't exist everywhere */ 275 #ifndef HOST_NAME_MAX 276 #if defined(_POSIX_HOST_NAME_MAX) 277 #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX 278 #elif defined(MAXHOSTNAMELEN) 279 #define HOST_NAME_MAX MAXHOSTNAMELEN 280 #else 281 #define HOST_NAME_MAX 255 282 #endif 283 #endif 284 285 /* {{{ struct RedisSock */ 286 typedef struct { 287 php_stream *stream; 288 php_stream_context *stream_ctx; 289 zend_string *host; 290 int port; 291 zend_string *user; 292 zend_string *pass; 293 double timeout; 294 double read_timeout; 295 long retry_interval; 296 int max_retries; 297 struct RedisBackoff backoff; 298 redis_sock_status status; 299 int persistent; 300 int watching; 301 zend_string *persistent_id; 302 303 redis_serializer serializer; 304 int compression; 305 int compression_level; 306 long dbNumber; 307 308 zend_string *prefix; 309 310 short mode; 311 struct fold_item *head; 312 struct fold_item *current; 313 314 zend_string *pipeline_cmd; 315 316 zend_string *err; 317 318 int scan; 319 320 int readonly; 321 int reply_literal; 322 int null_mbulk_as_null; 323 int tcp_keepalive; 324 } RedisSock; 325 /* }}} */ 326 327 /* Redis response handler function callback prototype */ 328 typedef void (*ResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock *redis_sock, zval *z_tab, void *ctx); 329 typedef int (*FailableResultCallback)(INTERNAL_FUNCTION_PARAMETERS, RedisSock*, zval*, void*); 330 331 typedef struct fold_item { 332 FailableResultCallback fun; 333 void *ctx; 334 struct fold_item *next; 335 } fold_item; 336 337 typedef struct { 338 zend_llist list; 339 int nb_active; 340 } ConnectionPool; 341 342 typedef struct { 343 RedisSock *sock; 344 zend_object std; 345 } redis_object; 346 347 /** Argument info for any function expecting 0 args */ 348 ZEND_BEGIN_ARG_INFO_EX(arginfo_void, 0, 0, 0) 349 ZEND_END_ARG_INFO() 350 351 ZEND_BEGIN_ARG_INFO_EX(arginfo_key, 0, 0, 1) 352 ZEND_ARG_INFO(0, key) 353 ZEND_END_ARG_INFO() 354 355 ZEND_BEGIN_ARG_INFO_EX(arginfo_value, 0, 0, 1) 356 ZEND_ARG_INFO(0, value) 357 ZEND_END_ARG_INFO() 358 359 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_value, 0, 0, 2) 360 ZEND_ARG_INFO(0, key) 361 ZEND_ARG_INFO(0, value) 362 ZEND_END_ARG_INFO() 363 364 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_expire_value, 0, 0, 3) 365 ZEND_ARG_INFO(0, key) 366 ZEND_ARG_INFO(0, expire) 367 ZEND_ARG_INFO(0, value) 368 ZEND_END_ARG_INFO() 369 370 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_newkey, 0, 0, 2) 371 ZEND_ARG_INFO(0, key) 372 ZEND_ARG_INFO(0, newkey) 373 ZEND_END_ARG_INFO() 374 375 ZEND_BEGIN_ARG_INFO_EX(arginfo_pairs, 0, 0, 1) 376 ZEND_ARG_ARRAY_INFO(0, pairs, 0) 377 ZEND_END_ARG_INFO() 378 379 ZEND_BEGIN_ARG_INFO_EX(arginfo_nkeys, 0, 0, 1) 380 ZEND_ARG_INFO(0, key) 381 ZEND_ARG_VARIADIC_INFO(0, other_keys) 382 ZEND_END_ARG_INFO() 383 384 ZEND_BEGIN_ARG_INFO_EX(arginfo_dst_nkeys, 0, 0, 2) 385 ZEND_ARG_INFO(0, dst) 386 ZEND_ARG_INFO(0, key) 387 ZEND_ARG_VARIADIC_INFO(0, other_keys) 388 ZEND_END_ARG_INFO() 389 390 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_min_max, 0, 0, 3) 391 ZEND_ARG_INFO(0, key) 392 ZEND_ARG_INFO(0, min) 393 ZEND_ARG_INFO(0, max) 394 ZEND_END_ARG_INFO() 395 396 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_member, 0, 0, 2) 397 ZEND_ARG_INFO(0, key) 398 ZEND_ARG_INFO(0, member) 399 ZEND_END_ARG_INFO() 400 401 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_member_value, 0, 0, 3) 402 ZEND_ARG_INFO(0, key) 403 ZEND_ARG_INFO(0, member) 404 ZEND_ARG_INFO(0, value) 405 ZEND_END_ARG_INFO() 406 407 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_members, 0, 0, 2) 408 ZEND_ARG_INFO(0, key) 409 ZEND_ARG_INFO(0, member) 410 ZEND_ARG_VARIADIC_INFO(0, other_members) 411 ZEND_END_ARG_INFO() 412 413 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_timestamp, 0, 0, 2) 414 ZEND_ARG_INFO(0, key) 415 ZEND_ARG_INFO(0, timestamp) 416 ZEND_END_ARG_INFO() 417 418 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_offset, 0, 0, 2) 419 ZEND_ARG_INFO(0, key) 420 ZEND_ARG_INFO(0, offset) 421 ZEND_END_ARG_INFO() 422 423 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_offset_value, 0, 0, 3) 424 ZEND_ARG_INFO(0, key) 425 ZEND_ARG_INFO(0, offset) 426 ZEND_ARG_INFO(0, value) 427 ZEND_END_ARG_INFO() 428 429 ZEND_BEGIN_ARG_INFO_EX(arginfo_swapdb, 0, 0, 2) 430 ZEND_ARG_INFO(0, srcdb) 431 ZEND_ARG_INFO(0, dstdb) 432 ZEND_END_ARG_INFO() 433 434 ZEND_BEGIN_ARG_INFO_EX(arginfo_key_start_end, 0, 0, 3) 435 ZEND_ARG_INFO(0, key) 436 ZEND_ARG_INFO(0, start) 437 ZEND_ARG_INFO(0, end) 438 ZEND_END_ARG_INFO() 439 440 ZEND_BEGIN_ARG_INFO_EX(arginfo_echo, 0, 0, 1) 441 ZEND_ARG_INFO(0, msg) 442 ZEND_END_ARG_INFO() 443 444 ZEND_BEGIN_ARG_INFO_EX(arginfo_expire, 0, 0, 2) 445 ZEND_ARG_INFO(0, key) 446 ZEND_ARG_INFO(0, timeout) 447 ZEND_END_ARG_INFO() 448 449 ZEND_BEGIN_ARG_INFO_EX(arginfo_set, 0, 0, 2) 450 ZEND_ARG_INFO(0, key) 451 ZEND_ARG_INFO(0, value) 452 ZEND_ARG_INFO(0, opts) 453 ZEND_END_ARG_INFO() 454 455 ZEND_BEGIN_ARG_INFO_EX(arginfo_lset, 0, 0, 3) 456 ZEND_ARG_INFO(0, key) 457 ZEND_ARG_INFO(0, index) 458 ZEND_ARG_INFO(0, value) 459 ZEND_END_ARG_INFO() 460 461 ZEND_BEGIN_ARG_INFO_EX(arginfo_blrpop, 0, 0, 2) 462 ZEND_ARG_INFO(0, key) 463 ZEND_ARG_INFO(0, timeout_or_key) 464 ZEND_ARG_VARIADIC_INFO(0, extra_args) 465 ZEND_END_ARG_INFO() 466 467 ZEND_BEGIN_ARG_INFO_EX(arginfo_linsert, 0, 0, 4) 468 ZEND_ARG_INFO(0, key) 469 ZEND_ARG_INFO(0, position) 470 ZEND_ARG_INFO(0, pivot) 471 ZEND_ARG_INFO(0, value) 472 ZEND_END_ARG_INFO() 473 474 ZEND_BEGIN_ARG_INFO_EX(arginfo_lindex, 0, 0, 2) 475 ZEND_ARG_INFO(0, key) 476 ZEND_ARG_INFO(0, index) 477 ZEND_END_ARG_INFO() 478 479 ZEND_BEGIN_ARG_INFO_EX(arginfo_brpoplpush, 0, 0, 3) 480 ZEND_ARG_INFO(0, src) 481 ZEND_ARG_INFO(0, dst) 482 ZEND_ARG_INFO(0, timeout) 483 ZEND_END_ARG_INFO() 484 485 ZEND_BEGIN_ARG_INFO_EX(arginfo_rpoplpush, 0, 0, 2) 486 ZEND_ARG_INFO(0, src) 487 ZEND_ARG_INFO(0, dst) 488 ZEND_END_ARG_INFO() 489 490 ZEND_BEGIN_ARG_INFO_EX(arginfo_sadd_array, 0, 0, 2) 491 ZEND_ARG_INFO(0, key) 492 ZEND_ARG_ARRAY_INFO(0, options, 0) 493 ZEND_END_ARG_INFO() 494 495 ZEND_BEGIN_ARG_INFO_EX(arginfo_srand_member, 0, 0, 1) 496 ZEND_ARG_INFO(0, key) 497 ZEND_ARG_INFO(0, count) 498 ZEND_END_ARG_INFO() 499 500 ZEND_BEGIN_ARG_INFO_EX(arginfo_zadd, 0, 0, 3) 501 ZEND_ARG_INFO(0, key) 502 ZEND_ARG_INFO(0, score) 503 ZEND_ARG_INFO(0, value) 504 ZEND_ARG_VARIADIC_INFO(0, extra_args) 505 ZEND_END_ARG_INFO() 506 507 ZEND_BEGIN_ARG_INFO_EX(arginfo_zincrby, 0, 0, 3) 508 ZEND_ARG_INFO(0, key) 509 ZEND_ARG_INFO(0, value) 510 ZEND_ARG_INFO(0, member) 511 ZEND_END_ARG_INFO() 512 513 ZEND_BEGIN_ARG_INFO_EX(arginfo_hmget, 0, 0, 2) 514 ZEND_ARG_INFO(0, key) 515 ZEND_ARG_ARRAY_INFO(0, keys, 0) 516 ZEND_END_ARG_INFO() 517 518 ZEND_BEGIN_ARG_INFO_EX(arginfo_hmset, 0, 0, 2) 519 ZEND_ARG_INFO(0, key) 520 ZEND_ARG_ARRAY_INFO(0, pairs, 0) 521 ZEND_END_ARG_INFO() 522 523 ZEND_BEGIN_ARG_INFO_EX(arginfo_bitop, 0, 0, 3) 524 ZEND_ARG_INFO(0, operation) 525 ZEND_ARG_INFO(0, ret_key) 526 ZEND_ARG_INFO(0, key) 527 ZEND_ARG_VARIADIC_INFO(0, other_keys) 528 ZEND_END_ARG_INFO() 529 530 ZEND_BEGIN_ARG_INFO_EX(arginfo_bitpos, 0, 0, 2) 531 ZEND_ARG_INFO(0, key) 532 ZEND_ARG_INFO(0, bit) 533 ZEND_ARG_INFO(0, start) 534 ZEND_ARG_INFO(0, end) 535 ZEND_END_ARG_INFO() 536 537 ZEND_BEGIN_ARG_INFO_EX(arginfo_ltrim, 0, 0, 3) 538 ZEND_ARG_INFO(0, key) 539 ZEND_ARG_INFO(0, start) 540 ZEND_ARG_INFO(0, stop) 541 ZEND_END_ARG_INFO() 542 543 ZEND_BEGIN_ARG_INFO_EX(arginfo_publish, 0, 0, 2) 544 ZEND_ARG_INFO(0, channel) 545 ZEND_ARG_INFO(0, message) 546 ZEND_END_ARG_INFO() 547 548 ZEND_BEGIN_ARG_INFO_EX(arginfo_pfadd, 0, 0, 2) 549 ZEND_ARG_INFO(0, key) 550 ZEND_ARG_ARRAY_INFO(0, elements, 0) 551 ZEND_END_ARG_INFO() 552 553 ZEND_BEGIN_ARG_INFO_EX(arginfo_pfmerge, 0, 0, 2) 554 ZEND_ARG_INFO(0, dstkey) 555 ZEND_ARG_ARRAY_INFO(0, keys, 0) 556 ZEND_END_ARG_INFO() 557 558 ZEND_BEGIN_ARG_INFO_EX(arginfo_restore, 0, 0, 3) 559 ZEND_ARG_INFO(0, ttl) 560 ZEND_ARG_INFO(0, key) 561 ZEND_ARG_INFO(0, value) 562 ZEND_END_ARG_INFO() 563 564 ZEND_BEGIN_ARG_INFO_EX(arginfo_smove, 0, 0, 3) 565 ZEND_ARG_INFO(0, src) 566 ZEND_ARG_INFO(0, dst) 567 ZEND_ARG_INFO(0, value) 568 ZEND_END_ARG_INFO() 569 570 ZEND_BEGIN_ARG_INFO_EX(arginfo_zrange, 0, 0, 3) 571 ZEND_ARG_INFO(0, key) 572 ZEND_ARG_INFO(0, start) 573 ZEND_ARG_INFO(0, end) 574 ZEND_ARG_INFO(0, scores) 575 ZEND_END_ARG_INFO() 576 577 ZEND_BEGIN_ARG_INFO_EX(arginfo_zrangebyscore, 0, 0, 3) 578 ZEND_ARG_INFO(0, key) 579 ZEND_ARG_INFO(0, start) 580 ZEND_ARG_INFO(0, end) 581 ZEND_ARG_ARRAY_INFO(0, options, 0) 582 ZEND_END_ARG_INFO() 583 584 ZEND_BEGIN_ARG_INFO_EX(arginfo_zrangebylex, 0, 0, 3) 585 ZEND_ARG_INFO(0, key) 586 ZEND_ARG_INFO(0, min) 587 ZEND_ARG_INFO(0, max) 588 ZEND_ARG_INFO(0, offset) 589 ZEND_ARG_INFO(0, limit) 590 ZEND_END_ARG_INFO() 591 592 ZEND_BEGIN_ARG_INFO_EX(arginfo_zstore, 0, 0, 2) 593 ZEND_ARG_INFO(0, key) 594 ZEND_ARG_ARRAY_INFO(0, keys, 0) 595 ZEND_ARG_ARRAY_INFO(0, weights, 1) 596 ZEND_ARG_INFO(0, aggregate) 597 ZEND_END_ARG_INFO() 598 599 ZEND_BEGIN_ARG_INFO_EX(arginfo_sort, 0, 0, 1) 600 ZEND_ARG_INFO(0, key) 601 ZEND_ARG_ARRAY_INFO(0, options, 0) 602 ZEND_END_ARG_INFO() 603 604 ZEND_BEGIN_ARG_INFO_EX(arginfo_object, 0, 0, 2) 605 ZEND_ARG_INFO(0, field) 606 ZEND_ARG_INFO(0, key) 607 ZEND_END_ARG_INFO() 608 609 ZEND_BEGIN_ARG_INFO_EX(arginfo_subscribe, 0, 0, 2) 610 ZEND_ARG_ARRAY_INFO(0, channels, 0) 611 ZEND_ARG_INFO(0, callback) 612 ZEND_END_ARG_INFO() 613 614 ZEND_BEGIN_ARG_INFO_EX(arginfo_psubscribe, 0, 0, 2) 615 ZEND_ARG_ARRAY_INFO(0, patterns, 0) 616 ZEND_ARG_INFO(0, callback) 617 ZEND_END_ARG_INFO() 618 619 ZEND_BEGIN_ARG_INFO_EX(arginfo_unsubscribe, 0, 0, 1) 620 ZEND_ARG_INFO(0, channel) 621 ZEND_ARG_VARIADIC_INFO(0, other_channels) 622 ZEND_END_ARG_INFO() 623 624 ZEND_BEGIN_ARG_INFO_EX(arginfo_punsubscribe, 0, 0, 1) 625 ZEND_ARG_INFO(0, pattern) 626 ZEND_ARG_VARIADIC_INFO(0, other_patterns) 627 ZEND_END_ARG_INFO() 628 629 ZEND_BEGIN_ARG_INFO_EX(arginfo_eval, 0, 0, 1) 630 ZEND_ARG_INFO(0, script) 631 ZEND_ARG_INFO(0, args) 632 ZEND_ARG_INFO(0, num_keys) 633 ZEND_END_ARG_INFO() 634 635 ZEND_BEGIN_ARG_INFO_EX(arginfo_evalsha, 0, 0, 1) 636 ZEND_ARG_INFO(0, script_sha) 637 ZEND_ARG_INFO(0, args) 638 ZEND_ARG_INFO(0, num_keys) 639 ZEND_END_ARG_INFO() 640 641 ZEND_BEGIN_ARG_INFO_EX(arginfo_getoption, 0, 0, 1) 642 ZEND_ARG_INFO(0, option) 643 ZEND_END_ARG_INFO() 644 645 ZEND_BEGIN_ARG_INFO_EX(arginfo_setoption, 0, 0, 2) 646 ZEND_ARG_INFO(0, option) 647 ZEND_ARG_INFO(0, value) 648 ZEND_END_ARG_INFO() 649 650 ZEND_BEGIN_ARG_INFO_EX(arginfo_watch, 0, 0, 1) 651 ZEND_ARG_INFO(0, key) 652 ZEND_ARG_VARIADIC_INFO(0, other_keys) 653 ZEND_END_ARG_INFO() 654 655 ZEND_BEGIN_ARG_INFO_EX(arginfo_command, 0, 0, 0) 656 ZEND_ARG_VARIADIC_INFO(0, args) 657 ZEND_END_ARG_INFO() 658 659 ZEND_BEGIN_ARG_INFO_EX(arginfo_rawcommand, 0, 0, 1) 660 ZEND_ARG_INFO(0, cmd) 661 ZEND_ARG_VARIADIC_INFO(0, args) 662 ZEND_END_ARG_INFO() 663 664 ZEND_BEGIN_ARG_INFO_EX(arginfo_geoadd, 0, 0, 4) 665 ZEND_ARG_INFO(0, key) 666 ZEND_ARG_INFO(0, lng) 667 ZEND_ARG_INFO(0, lat) 668 ZEND_ARG_INFO(0, member) 669 ZEND_ARG_VARIADIC_INFO(0, other_triples) 670 ZEND_END_ARG_INFO() 671 672 ZEND_BEGIN_ARG_INFO_EX(arginfo_geodist, 0, 0, 3) 673 ZEND_ARG_INFO(0, key) 674 ZEND_ARG_INFO(0, src) 675 ZEND_ARG_INFO(0, dst) 676 ZEND_ARG_INFO(0, unit) 677 ZEND_END_ARG_INFO() 678 679 ZEND_BEGIN_ARG_INFO_EX(arginfo_georadius, 0, 0, 5) 680 ZEND_ARG_INFO(0, key) 681 ZEND_ARG_INFO(0, lng) 682 ZEND_ARG_INFO(0, lan) 683 ZEND_ARG_INFO(0, radius) 684 ZEND_ARG_INFO(0, unit) 685 ZEND_ARG_ARRAY_INFO(0, opts, 0) 686 ZEND_END_ARG_INFO() 687 688 ZEND_BEGIN_ARG_INFO_EX(arginfo_georadiusbymember, 0, 0, 4) 689 ZEND_ARG_INFO(0, key) 690 ZEND_ARG_INFO(0, member) 691 ZEND_ARG_INFO(0, radius) 692 ZEND_ARG_INFO(0, unit) 693 ZEND_ARG_ARRAY_INFO(0, opts, 0) 694 ZEND_END_ARG_INFO() 695 696 ZEND_BEGIN_ARG_INFO_EX(arginfo_xadd, 0, 0, 3) 697 ZEND_ARG_INFO(0, str_key) 698 ZEND_ARG_INFO(0, str_id) 699 ZEND_ARG_ARRAY_INFO(0, arr_fields, 0) 700 ZEND_ARG_INFO(0, i_maxlen) 701 ZEND_ARG_INFO(0, boo_approximate) 702 ZEND_END_ARG_INFO() 703 704 ZEND_BEGIN_ARG_INFO_EX(arginfo_xpending, 0, 0, 2) 705 ZEND_ARG_INFO(0, str_key) 706 ZEND_ARG_INFO(0, str_group) 707 ZEND_ARG_INFO(0, str_start) 708 ZEND_ARG_INFO(0, str_end) 709 ZEND_ARG_INFO(0, i_count) 710 ZEND_ARG_INFO(0, str_consumer) 711 ZEND_END_ARG_INFO() 712 713 ZEND_BEGIN_ARG_INFO_EX(arginfo_xrange, 0, 0, 3) 714 ZEND_ARG_INFO(0, str_key) 715 ZEND_ARG_INFO(0, str_start) 716 ZEND_ARG_INFO(0, str_end) 717 ZEND_ARG_INFO(0, i_count) 718 ZEND_END_ARG_INFO() 719 720 ZEND_BEGIN_ARG_INFO_EX(arginfo_xread, 0, 0, 1) 721 ZEND_ARG_ARRAY_INFO(0, arr_streams, 0) 722 ZEND_ARG_INFO(0, i_count) 723 ZEND_ARG_INFO(0, i_block) 724 ZEND_END_ARG_INFO() 725 726 ZEND_BEGIN_ARG_INFO_EX(arginfo_xreadgroup, 0, 0, 3) 727 ZEND_ARG_INFO(0, str_group) 728 ZEND_ARG_INFO(0, str_consumer) 729 ZEND_ARG_ARRAY_INFO(0, arr_streams, 0) 730 ZEND_ARG_INFO(0, i_count) 731 ZEND_ARG_INFO(0, i_block) 732 ZEND_END_ARG_INFO() 733 734 ZEND_BEGIN_ARG_INFO_EX(arginfo_xack, 0, 0, 3) 735 ZEND_ARG_INFO(0, str_key) 736 ZEND_ARG_INFO(0, str_group) 737 ZEND_ARG_ARRAY_INFO(0, arr_ids, 0) 738 ZEND_END_ARG_INFO() 739 740 ZEND_BEGIN_ARG_INFO_EX(arginfo_xclaim, 0, 0, 5) 741 ZEND_ARG_INFO(0, str_key) 742 ZEND_ARG_INFO(0, str_group) 743 ZEND_ARG_INFO(0, str_consumer) 744 ZEND_ARG_INFO(0, i_min_idle) 745 ZEND_ARG_ARRAY_INFO(0, arr_ids, 0) 746 ZEND_ARG_ARRAY_INFO(0, arr_opts, 0) 747 ZEND_END_ARG_INFO() 748 749 ZEND_BEGIN_ARG_INFO_EX(arginfo_xgroup, 0, 0, 1) 750 ZEND_ARG_INFO(0, str_operation) 751 ZEND_ARG_INFO(0, str_key) 752 ZEND_ARG_INFO(0, str_arg1) 753 ZEND_ARG_INFO(0, str_arg2) 754 ZEND_ARG_INFO(0, str_arg3) 755 ZEND_END_ARG_INFO() 756 757 ZEND_BEGIN_ARG_INFO_EX(arginfo_xinfo, 0, 0, 1) 758 ZEND_ARG_INFO(0, str_cmd) 759 ZEND_ARG_INFO(0, str_key) 760 ZEND_ARG_INFO(0, str_group) 761 ZEND_END_ARG_INFO() 762 763 ZEND_BEGIN_ARG_INFO_EX(arginfo_xtrim, 0, 0, 2) 764 ZEND_ARG_INFO(0, str_key) 765 ZEND_ARG_INFO(0, i_maxlen) 766 ZEND_ARG_INFO(0, boo_approximate) 767 ZEND_END_ARG_INFO() 768 769 ZEND_BEGIN_ARG_INFO_EX(arginfo_xdel, 0, 0, 2) 770 ZEND_ARG_INFO(0, str_key) 771 ZEND_ARG_ARRAY_INFO(0, arr_ids, 0) 772 ZEND_END_ARG_INFO() 773 774 #endif 775