Previously, the redis.session.early_refresh feature was implemented for
Redis Cluster, utilizing GETEX for the initial session read to minimize
the number of commands sent to the Redis server. However, this enhancement
was not applied to non-cluster sessions. This update addresses this
discrepancy, ensuring consistent behavior between Redis and Redis Cluster.
When a node timeout occurs, then phpredis will try to connect to another
node, whose answer probably will be MOVED redirect. After this we need
more time to accomplish the redirection, otherwise we get "Timed out
attempting to find data in the correct node" error message.
Fixes#795#888#1142#1385#1633#1707#1811#2407
Mention support for KeyDB in README.md.
Remove credit for Owlient from the first paragraph. Owlient was acquired by Ubisoft in 2011, so presumably no longer benefit from such prominent credit.
This commit fixes our unit tests so they also pass against the KeyDB
server. We didn't ned to change all that much. Most of it was just
adding a version/keydb check.
The only change to PhpRedis itself was to relax the reply requirements
for XAUTOCLAIM. Redis 7.0.0 added a third "these elements were recently
removed" reply which KeyDB does not have.
Fixes#2466
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.
PHP 8.4 has some breaking changes with respect to where PHP's random methods and
helpers are. This commit fixes those issues while staying backward compatible.
Fixes#2463
We also need to update the `RedisCluster` logic to handle very large
curosr values, in addition to handling them for the `Redis` and
`RedisArray` classes.
See #2454, #2458
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
We actually had two different bits of logic to handle EXPIRY values in
the `SET` command. One for the legacy `SET` -> `SETEX` mapping and
another for the newer `SET foo bar EX <expiry>`.
Additionally the error message could be confusing. Passing 3.1415 for
an `EX` expiry would fail as we didn't allow floats.
This commit consolidates expiry parsing to our existing helper function
as well as improves the `php_error_docref` warning in the event that the
user passes invalid data. The warning will now tell the user the type
they tried to pass as an EXPIRY to make it easier to track down what's
going wrong.
Fixes#2448
* Add what value failed to pass our callback assertion so we can see
what we actually got from the server.
* WAITAOF requires Redis >= 7.2.0 so don't run it if the server is older
than that.
* We weren't properly passing `z_tab` through to the underlying OBJECT
handler, which was causing PhpRedis to crash if you tried to execute
the OBJECT command in a pipeline.
* Rework the `testTouch` unit test to try and avoid erroneous failures
due to CI instance CPU scheduling.
* Use the pattern Redis provides us not the channel, if this is
a wildcard based `PSUBSCRIBE` payload.
* Don't test whether our slots match in `SSUBSCRIBE` when not in cluster
mode.
Fixes#2395