146 Commits

Author SHA1 Message Date
Pavlo Yatsukhnenko
7d3b2e4d6d Add hGetWithMeta method 2025-10-06 16:22:59 -07:00
michael-grunder
6ce3bd533a Implement VRANGE command and add a test 2025-10-02 11:12:39 -07:00
michael-grunder
92137ffd3f We actually do return bool in sismember so do the same here 2025-09-01 09:41:12 -07:00
michael-grunder
92dd256f98 Implement VISMEMBER command. 2025-09-01 09:41:12 -07:00
michael-grunder
d80b725824 Implement VGETATTR command 2025-09-01 09:41:12 -07:00
michael-grunder
7f9b1f416e Implement VLINKS command 2025-09-01 09:41:12 -07:00
michael-grunder
92716ed0c5 Implement VSETATTR command 2025-09-01 09:41:12 -07:00
michael-grunder
dc91631b3f Implement VREM command
See #2543
2025-09-01 09:41:12 -07:00
michael-grunder
1deca62841 Implement VRANDMEMBER
`VRANDMEMBER` has the exact same semantics of `SRANDMEMBER` so make
`SRANDMEMBER` a keyword based command and use it for `VRANDMEMBER`.

See #2543
2025-09-01 09:41:12 -07:00
michael-grunder
96378b70fd Implement VEMB and slightly rework VINFO
Unfortunately `VEMB` has a unique `RESP2` reply as far as I can tell,
where it sends the embedding mode (int8, bin, fp32) as a simple string.

This would cause any of PhpRedis' generic reply handlers to turn that
into `true` which isn't useful. For that reason we need a custom reply
handler.

Additionally slightly rework `VINFO` to short circuit and return failure
if we read anything other than a bulk string or an integer reply type.
Otherwise we may get out of sync on the socket.

See #2543
2025-09-01 09:41:12 -07:00
michael-grunder
0fda9f293b Implement VCARD, VDIM, and VINFO
All of these commands have the same form `<cmd> key`. `VINFO` is a bit
of an outlier however that uses simple strings as opposed to bulk
strings for the key names, meaning we had to create a custom handler.

See #2543
2025-09-01 09:41:12 -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
b1b0c19142 Implement DELIFEQ command
Implement the command and add a test.
2025-08-24 06:37:28 -07:00
michael-grunder
d1d690053f Implement VSIM command
This command is similar to `VADD` in that it's pretty simple but allows
for a great many options.

In it's most basic form:

```php
// To get similarity of a different element
$redis->vsim('myvec', 'some-element');

// To get similarity for a vector of scores
```

As seen above the method attempts to infer element or vector from the
argument passed to $member`. However, since we do serialize the member
when doing `ELE` mode, the user can also specify `ELE` explicitly in the
options array to force an `ELE` search sending serialized values.

```php
$redis->setOption(Redis::OPT_SERIALIZER, Redis::SERIALIZER_PHP);
$redis->vsim('myvec', [3.14, 2.71], ['ELE']);
```

See #2543
2025-07-31 08:30:47 -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
Michael Grunder
ce5b0facc2 Implement HGETEX, HSETEX, HGETDEL, and refactor HMGET (#2667)
* Rework HMGET and implement HGETEX

Instead of using a bespoke NULL terminated `zval**` array for the
context array we can use a `HashTable`. This might be a tiny bit more
expensive but Zend hashtables are quite efficient and this should also
be less error prone.

* Rework our `HashTable` context array to store keys

Instead of sending an array of values we can instead add the fields as
keys to our context array. That way when we combine the keys with the
Redis provided values we can do it in-place and then just give the
HashTable to the user to then do with what they want.

* Implement HGETDEL command.

* Fix edge cases to abide by legacy behavior.

Previously we coerced integer strings into integer keys when zipping
`HMGET` responses. This commit adds logic so we continue to do this and
do not change semantics.

* Implement `HGETDEL` and `HGETEX` for `RedisCluster`.

This commit implements the new commands and reworks the `HMGET` reply
handler to use the new context `HashTable`.

* Fix an edge case where we get zero multiblk elements

* Tests for `HGETEX` and `HGETDEL`

* Minor logic improvement

We don't need to check if `c->reply_len > 0` in the last else block
since we have already determined it must be.

* Implement `HSETEX` for `Redis` and `RedisCluster`

* Use `zval_get_tmp_string` ro populating non-long keys
2025-07-16 16:46:09 -07:00
michael-grunder
7350768cd9 Implement several hash expiration commands
Commands implemented:

`H[P]EXPIRE`
`H[P]TTL`
`H[P]EXPIREAT`
`H[P]EXPIRETIME`
`HPERSIST`
2025-05-07 08:16:14 -07:00
michael-grunder
b48aa0d471 Fix an unused variable warning 2025-04-20 10:18:30 -07:00
Pavlo Yatsukhnenko
cbaf095ff7 Allow calling methods only in atomic mode 2025-03-20 10:38:56 -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
abb0f6ccc8 Add details to the option doc block 2025-02-05 14:12:42 -08: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
michael-grunder
3f8dba6a44 Regnerate stub hash 2025-01-13 11:08:28 -08:00
michael-grunder
4cd3f59356 Implement KeyDB's EXPIREMEMBER[AT] commands 2024-11-15 08:59:10 -08:00
Viktor Djupsjöbacka
6ea5b3e08b Fix argument count issue in HSET with associative array, update method signature for HSET and add documentation 2024-07-17 12:47:49 -07:00
michael-grunder
6673b5b2be SRANDMEMBER can return any type because of serialization. 2024-07-13 23:12:25 -07:00
Michael Grunder
99f9fd8353 Fix HRANDFIELD command when WITHVALUES is used. (#2524)
Redis requires the user to send a count if `WITHVALUES` is specified,
otherwise it sees the `WITHVALUES` argument as the count and will error
out that it's not a number.

We can also return false if the key doesn't exist.
2024-07-13 22:42:25 -07:00
michael-grunder
34b5bd81ef Rework how we declare ZSTD min/max constants.
Fixes #2487
2024-05-16 11:44:52 -07:00
Pavlo Yatsukhnenko
50e5405c03 Fix Arginfo / zpp mismatch for DUMP command 2024-03-25 19:28:29 +02:00
michael-grunder
e52f0afaed Update SCAN to handle very large cursor values.
Technically Redis may return any unsigned 64 bit integer as a scan
cursor.  This presents a problem for PHP in that PHP's integers are
signed.  Because of that if a scan cursor is > 2^63 it will overflow and
fail to work properly.

This commit updates our SCAN family of commands to deliver cursors in
their string form.

```php
public function scan(null|int|string $iterator, ...);
```

On initial entry into our SCAN family we convert either a NULL or empty
string cursor to zero, and send the initial scan command.

As Redis replies with cursors we either represent them as a long (if
they are <= ZEND_ULONG_MAX) and as a string if greater.  This should
mean the fix is minimally breaking as the following code will still
work:

```php
$it = NULL;
do {
    print_r($redis->scan($it));
} while ($it !== 0);
```

The `$it !== 0` still works because the zero cursor will be represented
as an integer.  Only absurdly large (> 2^63) values are represented as a
string.

Fixes #2454
2024-03-17 10:59:14 -07:00
michael-grunder
fa1a283ac9 Fix some typos 2024-03-13 13:46:58 -07:00
michael-grunder
4d233977a5 Update stubs 2024-03-13 13:07:26 -07:00
michael-grunder
ed7c9f6f63 Implement WAITAOF command. 2024-02-14 12:03:29 -08:00
Pavlo Yatsukhnenko
5d293245cd Fix Redis::mget signature 2024-01-16 13:43:51 -08:00
michael-grunder
ff305349db Update generated stubs
See #2398
2023-10-30 10:51:23 -07:00
michael-grunder
12966a7413 Update generated stubs 2023-10-27 11:46:23 -07:00
michael-grunder
ccd419a4c8 Small refactor of some methods
* Use our `redis_cmd_append_sstr_key_*` and `redis_cmd_append_sstr_zval`
  wrappers, which handle key prefixing and serialization transparently.

* Rework ZADD so it can handle the bulk double response from the `INCR`
  options.
2023-03-01 11:45:47 -08:00
Pavlo Yatsukhnenko
7c46ad2c05 Issue #2068
Add FCALL/FCALL_RO commands
2022-12-24 13:37:50 +02:00
Pavlo Yatsukhnenko
90a0e9cc0e Add Redis::function command 2022-12-18 18:21:42 +02:00
michael-grunder
aa0938a4e2 Rework ZRANGE argument handling.
Rework argument parsing for `ZRANGE` so we can pass either a string or
an integer so everything will work even when using strict types.

Additionally update our docs to use the correct mechanism for adding
the `BYSCORE` option.

Fixes #2291
2022-12-10 12:00:09 -08:00
michael-grunder
19fd7e0c00 Refactor PFCOUNT command. 2022-12-10 11:58:08 -08:00
michael-grunder
121e9d9c29 Implement BLMOVE and add LMOVE/BLMOVE to cluster.
* Refactor `redis_lmove_cmd` to work for both `LMOVE` and `BLMOVE`
* Implement `LMOVE` and `BLMOVE` in RedisCluster.

See #1894
2022-12-01 13:48:03 -08: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
michael-grunder
2a6dee5d4d Use PHP's new class constant mechanism.
Let gen_stub.php define the constants for us, including deriving their
actual values from C defines.

As a side-effect we have to drop support for PHP < 7.2 as it does not
have interned strings.
2022-11-24 09:26:44 -08:00
Pavlo Yatsukhnenko
ff863f3f97 Refactor command command
Issue #2068
2022-11-19 14:04:38 +02:00
michael-grunder
0b7bd83f57 Add more docblocks and fix XAUTOCLAIM response handler.
- Finish adding docblocks with examples for all of the stream commands.
- Fix XAUTOCLAIM response handler (the reply has a slightly different
  structure to XCLAIM.
2022-11-15 23:29:45 -08:00
michael-grunder
c14a9e3a01 Documentation: Normalize examples. 2022-11-15 18:16:57 -08:00
michael-grunder
ef4699c726 Documentation: Rework more formatting and add example sections.
[skip ci]
2022-11-10 19:36:06 -08:00