278 Commits

Author SHA1 Message Date
Pavlo Yatsukhnenko
7d3b2e4d6d Add hGetWithMeta method 2025-10-06 16:22:59 -07:00
Remi Collet
f5db01b781 fix testXGrous expectation for change in redis 8.2.2 2025-10-03 06:03:36 -07:00
michael-grunder
6ce3bd533a Implement VRANGE command and add a test 2025-10-02 11:12:39 -07:00
michael-grunder
f24814a423 Fix geosearchstore bypolygon test
In cluster mode the destination and source keys must hash to the same
slot.
2025-09-10 11:56:49 -07:00
michael-grunder
b3da0f3bcf Remove a "bad argument" assertion for testWait
It seems like Redis changed what it will do when you send a negative
number of events. Previously this would just return an error but it
seems to return `1` now.

For this reason just remove that assertion so we don't have to use
different logic depending on the version of the server.
2025-09-10 11:33:35 -07:00
michael-grunder
22a2914b09 Add a regression test 2025-09-09 16:30:43 -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
0b4b4ed2c3 Add a test for VGETATTR 2025-09-01 09:41:12 -07:00
michael-grunder
ea11d62aec Test for VSETATTR 2025-09-01 09:41:12 -07:00
michael-grunder
5fe188416d Add a test for VRANDMEMBER 2025-09-01 09:41:12 -07:00
michael-grunder
bbae745a93 Add a test for VREM
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
8f8a49bec2 Tests for VCARD, VDIM, and VINFO. 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
8d369f4d62 Implement GEOSEARCH[STORE] BYPOLYGON.
Valkey 9.0.0 implemented a new variant of `GEOSEARCH` where you supply
the verticies to an arbitrary polygon.

Since we can't modify the `geosearch` prototype using it is a little
wonky (you need to just pass empty strings for position and unit).

```php
$redis->geosearch('ca:cities', '', [
    -121.90, 39.65, -121.77, 39.65, -121.77, 39.80, -121.90, 39.80
], '');
$redis->geosearchstore('ca:cities', 'dst', '', [
    -121.90, 39.65, -121.77, 39.65, -121.77, 39.80, -121.90, 39.80
], '');
```
2025-08-24 06:37:51 -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
b83981aaeb Rework HEXPIRE test inclusion + bump Valkey (#2684)
* Rework `HEXPIRE` test inclusion + bump Valkey

* Add a little `haveCommand` helper which uses `COMMAND INFO` to check
  if a given server has a specific command. This way when we bump valkey
  to an official release that supports the commands we will start
  testing.
* Bump Valkey from 7.2.5 to 8.1.3 which is much newer.

* Rework `haveCommand` to explicitly check for the command name

COMMAND INFO will return the command name as one of the first bits of
data so we can check for it that way.

* Fix incorrect logic
2025-08-06 10:08:49 -07:00
michael-grunder
6e5faf4226 Refactor EVAL[SHA] command and add a regression test
* We can make the code simpler by using `zend_empty_array` when no args
  are passed as well as the new argument parsing macros and newer internal
  redis command appending functions that take zend strings.

* Add a regression test for when we execute `EVAL[SHA]` with arguments
  but do not send any keys. This was causing UB in RedisCluster (#2681).
2025-08-05 13:20:36 -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
152fdda9b1 Fix double -> int truncation warning 2025-05-08 09:19:12 -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
593ba012ac Check for dragonfly_version in HELLO response
DragonflyDB will report to be Redis but also include `dragonfly_version`
in the hello response, which we can use to identify the fork.

Also fix parsing of the `HELLO` response for `serverName()` and
`serverVersion()`. Starting in Redis 8.0 there seem to always be modules
running, which the previous function was not expecting or parsing.
2025-05-05 09:31:11 -07:00
Michael Grunder
0445e683e7 Refactor getWithMeta logic (#2643)
* Refactor `getWithMeta`

* Consolidate `getWithMeta()` test.

* Review comments
2025-03-31 12:42:29 -07:00
Jakub Onderka
4f6a3ed1e7 New option 'database' for Redis class constructor (#2597)
* New option 'database' for Redis class constructor

Selecting database is very common action after connecting to Redis. This simplifies lazy connecting to Redis, when requested database will be selected after first command.

* More specific exception message when invalid auth or database number is provided

Before it was just 'Redis server went away'

* Rename reselect_db method to redis_select_db and slightly optimise it
2025-03-26 18:05:33 -07:00
Remi Collet
3828c9293b cleanup session temp file (#2641)
* cleanup session temp file

* Fix Deprecated: Automatic conversion of false to array
2025-03-26 15:25:22 -07:00
michael-grunder
300c5fb218 Make execHello protected
This lets a subclass override it
2025-03-21 11:23:58 -07:00
michael-grunder
fa3eb00683 Add tests for serverName() and serverVersion() 2025-03-20 14:18:44 -07:00
michael-grunder
d342e4ac18 Implement GETDEL for RedisCluster
Fixes #2629
2025-03-06 10:06:26 -08:00
Pavlo Yatsukhnenko
807f806fe8 Reorganize tests 2025-02-25 17:40:23 +02: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
michael-grunder
a2eef77f44 Implement Valkey >= 8.1 IFEQ set option
Implement the new `IFEQ` `SET` option that will be included in `Valkey`
8.1.

See: valkey-io/valkey#1324
2025-01-20 08:04:27 -08:00
Jakub Onderka
426de2bb71 Test for empty pipeline and multi 2024-11-26 10:39:23 -08:00
michael-grunder
4cd3f59356 Implement KeyDB's EXPIREMEMBER[AT] commands 2024-11-15 08:59:10 -08:00
Remi Collet
cc1be32294 fix 2 tests with redis 6.2 2024-09-24 14:47:04 +02: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 Dwyer
eeb5109967 Update documentation (#2523)
* Remove/update mentions of removed methods

These methods were deprecated in a previous release

* Correct documentation for zInter/zinterstore

* Correct documentation for zUnion/zunionstore

* Add documentation for zDiff/zdiffstore

* Add documentation for zMscore
2024-07-11 21:49:29 -07:00
michael-grunder
981c69314d Add GETEX to README docs + minor change to command.
* Adds `GETEX` to the README.md documentation.
* Allow the user to send `PERSIST` either as an array key or just in the
  array, to conform with similar methods.
* Implement getEx for `RedisCluster`

Fixes #2512
2024-06-20 13:56:17 -07:00
Michael Grunder
57304970cd PHP might throw a fatal error if we send no args to exists (#2510) 2024-06-18 16:05:21 -07:00
Michael Grunder
b1771defdc More unit test utility functions/usage. (#2509)
* More unit  test utility functions/usage.

* Add `assertKeyEquals` and `assertKeyEqualsWeak` as we test key values
  hundreds of places in `RedisTest.php`

* We are almost always using `$this->redis` when we want to run an
  assertion that needs access to the client, so make this argument
  optional and default to `$this->redis`.

* Update a few more assertions to use our new methods.

* Various minor fixes/tweaks.

* Update RedisTest.php

typo
2024-06-18 14:53:22 -07:00
michael-grunder
b808cc60ed Update tests so they can run in php-cgi.
This probably isn't a very common scenerio since we've never had someone
ask it in a decade, but it was very simple to get them working.

Primarily we just needed to test for `STDTOUT`/`STDERR` and use
`__DIR__` instead of `$_SERVER['PHP_SELF']`.

Fixes #2507
2024-06-17 11:46:44 -07:00
michael-grunder
d3b2d87b10 Don't use $k1 as a variable name.
There is a very strange edge case whn you try to run PHP under valgrind
and use certain specific strings like "$k1".

PHP interns these values in such a way that valgrind can't handle it and
hard aborts on sigsegv.  I don't know what the actual cause is but
simply renaming the variables is a workaround.
2024-06-01 17:35:58 -07:00
michael-grunder
dab6a62d34 Code formatting 2024-05-31 12:15:54 -07:00
michael-grunder
c6cd665bde Code formatting 2024-05-30 12:10:46 -07:00
michael-grunder
78b70ca8f4 More test refactoring.
* Switch remaining old-style PHP 5.4 `Array(...)` declarations to `[...]`
* Update variable names getting rid hungarian notation prefixes (e.g.
  `str_`, `i_`, etc).
* Allow cluster seeds to be passed on the command-line instead of soley
  relying on either a node environment variable or our
  tests/nodes/nodemap file.  This should make it easier to run ad-hoc
  cluster tests by specifying just a single seed.
* Add some diagnostics for when we can't find a suitable cluster to run
  our tests against indicating exactly where we looked for the env var
  and node file.
* Refactor RedisArray tests to use our newer TestSuite assertions.
* Allow `RedisArray` ports to be specified on the command-line as well.
* Various formatting fixes.
* More robust KeyDB detection.
2024-05-29 23:02:29 -07:00