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
* Add compression support for PHP Sessions
Previously, compression was available for standard data but not for
session handling. This update enables the compression of PHP sessions,
allowing for more efficient Redis memory usage.
* Move session compress/uncompress logic to helper functions
* Change session_compress_data to always set the out arguments and adjust PS_READ_FUNC
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
* fix bug: the pipeline mode socket return an unexpected result after reconnecting
* fix typos: pipeline is right
---------
Co-authored-by: marcofu <marcofu@tencent.com>
* 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.
* Use our common command handler logic for SELECT.
* Shift updating `redis_sock->dbNumber` from the command itself to the
reply handler, so we aren't erroneously pointing to a non-existent
database before the command succeeds.
* Add ini setting redis.session.early_refresh to allow for session TTL updates on session start ( requires redis server version 6.2 or greater )
* Enable cluster session support for strict mode sessions ( via PS_VALIDATE_SID_FUNC )
* Cluster sessions used to write on every session, now we only write if the session has been modified.
* Send EXPIRE instead of SETEX if sessioh has not been changed
* If early refresh is enabled use GETEX for initial session read
* When strict sessions are enabled, check whether the session exists first, validate sid and regenerate if necessary
* 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
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.
Add additional complete docblocks for a few more commands.
Refactor SLAVEOF handler to conform with more modern PhpRedis command
handlers.
Create REPLICAOF and deprecate SLAVEOF as Redis has done since 5.0.0.
Implement the TOUCH command and refactor several of our "variadic key"
commands, which were previously all using their own specific handlers.
While refactoring the code, I changed `EXISTS` to require one key (it
had previously been set to require zero keys).
Additonally, it looks like we had a disparity in two commands which
should be idential to PhpRedis: SINTERSTORE and SUNIONSTORE.
Previously, SINTERSTORE required only one argument but SUNIONSTORE 2.
I simply changed SUNIONSTORE to also only require a single argument,
since that argument could be an array.
```php
$redis->sInterStore(['dst', 'src1', 'src2']);
$redis->sUnionStore(['dst', 'src1', 'src2']);
```
* Add ZRANGESTORE command.
* Add Redis 6.2's `REV`, `BYLEX`, and `BYSCORE` to ZRANGE options.
* Refactor several ZRANGE family commands into a single reply and
options handler, using PHP's new argument parsing macros.
* Extend our tests to use the new ZRANGE options.
See #1894
Refactor the slowlog command to use the new argument parsing API and
also change it so we no longer manually handle atomic/non-atomic
logic in the handler itself.
Redis 7.0.0 allows for getting and setting multiple config values as an
atomic operation. In order to support this while maintaining backward
compatibility, the CONFIG command is reworked to also accept an array of
values or keys and values.
See: #2068