244 Commits

Author SHA1 Message Date
Pavlo Yatsukhnenko c2d2254e56 Switch to Fast Parameter Parsing API 2026-06-04 13:25:11 -07:00
michael-grunder 2c5ef19257 Introduce new RedisCmd based command construction
* Introduce a new `RedisCmd` struct to dynamically append RESP arguments
  such that we don't have to precalculate the number of arguments the
  command will have up front.

  Additionally the new `RedisCmd allows both a `void *` context pointer
  but also can attach a `void (*ctx_dtor)(void*)` destructor so we are
  still able to clean up any allocated context when commands fail.

  This moves the context cleanup out of every individual reply handler
  and into the generic processing wrappers.

* Create a small group of `resp_str` helper functions for lower level
  concatination of RESP protocol data over the wire.

* Lots of small modernization of the codebase such as using
  `zend_string*` instead of (`char *`, `size_t`) pairs.

* Greatly simplify `crosslot` handling logic
2026-06-04 12:16:35 -07:00
michael-grunder e39d9b74f4 Modernize session locking
Add support for Redis' `DELEX` and Valkey's `DELIFEQ` when deleting the
session lock key. Local testing shows about a 10-15% improvement over
the current `EVAL[SHA]` strategy.

This commit adds a new INI settingg:
```ini
redis.session.lock_release_cmd = delex|delifeq|eval
```

By default we continue to use the `EVAL` logic and if a user specifies
another mechanism but the command doesn't exist, we warn the user and
fall back to EVAL.

This commit also refactors a few functions to avoid UB and simplify key
construction.
2026-03-01 14:52:39 -08:00
michael-grunder b97951cddc Rework TLS context logic
Instead of currying around a `php_stream_context` object, just retain
the context array provided by the user itself like we do with other
connection information like host and port. This lets users reconnect in
a loop without leaking memory.

```php
$redis = new \Redis;
while (true) {
    // Previously each reconnect call would leak the
    // `php_stream_context` structure.
    $redis->connect('tls://127.0.0.1', 9999, 1, null, 0, 0, [
        'stream' => ['verify_peer' => false, 'verify_peer_name' => false],
    ]);

    $redis->ping();

    $redis->close();
}
```
2026-02-18 09:46:55 -08:00
michael-grunder b192b0e454 Try to fix an ifdef compilation issue
Fixes #2775
2025-11-16 14:18:35 -08:00
michael-grunder 547475295a Introduce "must use attribute"
Conditionally add `[[nodiscard]]` (c23) or
`__attribute__((warn_unused_result))` when the compiler supports it.

This commit initially just adds iit to `cluster_map_keyspace` but we can
go throughour API adding it where appropriate.
2025-10-06 12:52:36 -07:00
michael-grunder 0ed0fc0562 Add Redis::REDIS_VECTORSET type.
Redis >= 8.0 has a new type `vectorset` that we should support like all
the other types.
2025-08-28 09:34:07 -07:00
michael-grunder a0621555b5 Reduce to < 80 chars 2025-08-21 08:53:51 -07:00
michael-grunder 7769194757 Change int flags to zend_bool since we only use them as booleans 2025-08-21 08:53:51 -07:00
michael-grunder 9802fc0e46 Rework REDIS_SAVE_CALLBACK to be a function. 2025-08-21 08:53:51 -07:00
michael-grunder 58e1a04f76 Remove wrapper macro which hides branching logic
This wrapper macro implicitly defines an `} else {` block but this is
not clear at the callsite which obsures what is actually going on.

There's no real advantage to the wrapping macro. Instead just call the
underlying macro in an explicit else branch.
2025-08-21 08:53:51 -07:00
michael-grunder 8f0931bbed Rework REDIS_PROCESS_REQUEST to be a function. 2025-08-21 08:53:51 -07:00
michael-grunder 7c953d458b Remove dead legacy code. 2025-08-21 08:53:51 -07:00
michael-grunder 950d2bc79d Rework REDIS_PROCESS_KW_CMD as a function 2025-08-21 08:53:51 -07:00
michael-grunder 601ebbff2b Rework REDIS_PROCESS_CMD into a static function 2025-08-21 08:53:51 -07:00
michael-grunder 286fa63064 Implement VADD command
This is for Redis 8.0's vector sets.

The command itself can be quite complex with all of the various options but
pretty simple using all defaults.

```php
$redis->vadd('myvec', [3.14, 2.17], 'myelement');
```

The implementation takes a default argument `$options` which can be an array in
order to specify the myriad of other knobs users can send. We just do a bit of
validation on inputs (e.g. certain numeric options must be positive) and make
sure the command is constructed in a valid way (e.g. REDUCE <dim> must come
before the floating point values).

By default we deliver `FP32` blobs but allow the user to send `VALUES` in the
options array which will cause PhpRedis to send N individual values. Sending
values is slower but might be nice for debugging (e.g. watching monitor)

See #2543
2025-07-31 00:57:28 -07:00
Wyatt OʼDay 9cae7815da Make changes requested by @yatsukhnenko 2025-07-30 09:37:32 -07:00
Wyatt OʼDay d18db84c68 Link to the correct header 2025-07-30 09:37:32 -07:00
Wyatt OʼDay 1e6f5477cb Fix compiling with PHP 8.5.0 alpha3 and newer 2025-07-30 09:37:32 -07:00
michael-grunder 75acbb0984 Remove unused macros + simplify some logic 2025-07-18 08:43:22 -07:00
Michael Grunder 0445e683e7 Refactor getWithMeta logic (#2643)
* Refactor `getWithMeta`

* Consolidate `getWithMeta()` test.

* Review comments
2025-03-31 12:42:29 -07:00
Pavlo Yatsukhnenko 056c2dbee7 Introduce Redis::serverName and Redis::serverVersion methods
Right now we can't implement `HELLO` command to switch protocol
because we don't support new reply types that come with RESP3.
But we can use `HELLO` reply to expose some server information.
2025-03-20 10:38:56 -07:00
Pavlo Yatsukhnenko 9036ffca6a Add getWithMeta method 2025-02-25 16:27:10 +02:00
michael-grunder f9ce9429ef Introduce Redis::OPT_PACK_IGNORE_NUMBERS option.
Adds an option that instructs PhpRedis to not serialize or compress
numeric values. Specifically where `Z_TYPE_P(z) == IS_LONG` or
`Z_TYPE_P(z) == IS_DOUBLE`.

This flag lets the user enable serialization and/or compression while
still using the various increment/decrement command (`INCR`, `INCRBY`,
`DECR`, `DECRBY`, `INCRBYFLOAT`, `HINCRBY`, and `HINCRBYFLOAT`).

Because PhpRedis can't be certain that this option was enabled when
writing keys, there is a small runtime cost on the read-side that tests
whether or not the value its reading is a pure integer or floating point
value.

See #23
2025-02-05 14:12:42 -08:00
Jakub Onderka a551fdc94c Switch from linked list to growing array for reply callbacks
Reduce allocation and deallocation count and also memory usage when using pipelining
2024-12-09 10:40:39 -08:00
Jakub Onderka 571ffbc8e0 Switch pipeline_cmd from smart_str to smart_string
As we don't need to extract zend_string from pipeline_cmd, we can use simple smart_string structure
2024-12-01 11:39:55 -08:00
Jakub Onderka b665925eed Use smart str for constructing pipeline cmd 2024-11-25 09:41:27 -08:00
michael-grunder 085d61ecfb Create a strncmp wrapper
On some glibc implementations strncmp is a macro. This commit simply creates a
`redis_strncmp` static inline wrapper function so we can `ZEND_STRL` instead of
manually counting the length or using `sizeof(s)-1` each time.

Fixes #2565
2024-10-15 10:40:15 -07:00
Pavlo Yatsukhnenko a9e53fd16e Fix segfault and remove redundant macros
Replace `SOCKET_WRITE_COMMAND` with `redis_sock_write` because it can't be used
with pre-defined commands (it frees memory in case of failed writing operation).
After replacement `SOCKET_WRITE_COMMAND` becomes redundant so remove it.
2024-03-21 15:14:36 +02:00
Pavlo Yatsukhnenko 7a055cada8 Use on-stack allocated valiables 2023-04-02 18:44:11 +03:00
Pavlo Yatsukhnenko 6930a81cb4 Auto-select db in redis_sock_server_open 2023-04-02 14:24:41 +03:00
Pavlo Yatsukhnenko 7644736e13 Issue #2068, ssubscribe/sunsubscribe 2022-12-01 22:19:15 +02:00
michael-grunder 90828019de Refactor network IO tracking.
* Create inline wrappers of the low-level php_stream_* functions that
  also keep track of the number of bytes written/read.

* Change the logic to aggregate network traffic until the user
  explicitly "resets" it.  I think this will be a more common use-case
  (running many commands and then seeing overall network IO).

See #2106
2022-11-25 13:41:47 -08:00
Pavlo Yatsukhnenko d73f3f4b08 Issue #2106 2022-10-24 09:17:22 +03:00
michael-grunder 54a084e51c Refactor FLUSHDB and update docs.
Fixes #2096
2022-10-10 23:04:17 -07:00
michael-grunder 114d79d15b Implement AUTH/AUTH2 arguments for MIGRATE 2022-10-08 11:49:40 -07:00
michael-grunder c0e839f6ac LCS command
Implement the Redis 7.0.0 LCS command with tests.
2022-10-01 10:42:23 -07:00
Pavlo Yatsukhnenko 8e747ecec9 Merge pull request #2123 from phpredis/pubsub
Refactor subscribe/unsubscribe
2022-07-15 09:19:00 +03:00
Pavlo Yatsukhnenko de3635dad5 Change PHPREDIS_CTX_PTR type 2022-06-29 17:31:03 +03:00
Pavlo Yatsukhnenko 3c9e159c7e Refactor subscribe/unsubscribe 2022-06-28 18:18:38 +03:00
Pavlo Yatsukhnenko 8290212692 Merge pull request #2089 from phpredis/issue-1974
Issue #1974
2022-04-05 07:46:33 +03:00
Pavlo Yatsukhnenko 831d6118c4 Remove weird macroses 2022-04-04 21:04:00 +03:00
Pavlo Yatsukhnenko 42cbd88a18 Issue #1974 2022-04-02 17:58:52 +03:00
Michael Grunder a64a0c3785 Fix fallthrough warnings and refactor adding a score (#2049)
* Suppress implicit fallthrough warnings by using an attribute if we
  have it and a do { } while(0) if we don't.

* Move duplicated logic for appending a ZSET score to one utility
  function.
2022-01-20 10:54:57 -08:00
michael-grunder dfbbc8428a WIP: Experimental support to detect unconsumed data
This commit is an attempt at detecting unconsumed data on a socket when
we pull it from the connection pool.

Two new INI settings are introduced related to the changes:

redis.pconnect.pool_detect_dirty:

Value Explanation
----- ----------------------------------------------------------------
    0 Don't execute new logic at all.
    1 Abort and close the socket if we find unconsumed bytes in the
      read buffer.
    2 Seek to the end of our read buffer if we find unconsumed bytes
      and then poll the socket FD to detect if we're still readable
      in which case we fail and close the socket.

redis.pconnect.pool_poll_timeout:

The poll timeout to employ when checking if the socket is readable.
This value is in milliseconds and can be zero.
2021-09-27 10:15:33 -07:00
Pavlo Yatsukhnenko 7cc15ca209 [WIP] Add stub-based arginfo for Redis 2021-09-02 14:02:44 +03:00
Nathaniel Braun 18706d9271 Add support for exponential backoff on retry 2021-07-20 09:21:13 +00:00
Pavlo Yatsukhnenko 28de62202e [WIP] Issue #1894
Add IDLE argument to XPENDING command
2021-04-15 18:49:46 +03:00
Pavlo Yatsukhnenko 6aa9c0899c Add PHPREDIS_CTX_PTR magic value 2021-04-14 12:55:38 +03:00
Michael Grunder e61ee1da45 Normalize Redis callback prototypes and stop typecasting. (#1935) 2021-02-25 10:03:53 -08:00