A PHP extension for Redis
Other
9465
478
2111

Expected behaviour

Actual behaviour

I'm seeing this behaviour on

  • OS: Mac OS 12.1
  • Redis:6.2.6
  • PHP:8.1
  • phpredis:5.3.5

$ pecl install igbinary // 3.2.7
$ pecl install zstd
$ pecl install redis

Steps to reproduce, backtrace or example script

[13-Jan-2022 20:34:31] NOTICE: PHP message: PHP Warning: PHP Startup: Unable to load dynamic library 'redis.so' (tried: /usr/local/lib/php/pecl/20210902/redis.so (dlopen(/usr/local/lib/php/pecl/20210902/redis.so, 0x0009): symbol not found in flat namespace '_igbinary_serialize'), /usr/local/lib/php/pecl/20210902/redis.so.so (dlopen(/usr/local/lib/php/pecl/20210902/redis.so.so, 0x0009): tried: '/usr/local/lib/php/pecl/20210902/redis.so.so' (no such file), '/usr/local/lib/redis.so.so' (no such file), '/usr/lib/redis.so.so' (no such file))) in Unknown on line 0

Since Redis 6.0 released on 2020 a float value is allowed to define the timeout for brpop commands:

redis/redis@eca0187

https://redis.io/commands/brpop/

Starting with Redis version 6.0.0: timeout is interpreted as a double instead of an integer.

However on redis_commands.c a PHP error occurs if the timeout is not defined as LONG:

if (has_timeout && Z_TYPE(z_args[argc-1])!=IS_LONG) {
    php_error_docref(NULL, E_ERROR,
        "Timeout value must be a LONG");
    efree(z_args);
    return FAILURE;
}

Do you have any plans on updating this extension to support it?

Unfortunately my only solution at the moment is installing the predis library instead since I would like to set a timeout in milliseconds.

This is just another case of #1526. Creating a new Issue as per comment #1526 (comment)

Expected behaviour

Array
(
    [0] => ReflectionParameter Object
        (
            [name] => key
        )
    [1] => ReflectionParameter Object
        (
            [name] => count
        )
)

Actual behaviour

(
    [0] => ReflectionParameter Object
        (
            [name] => key
        )
)

I'm seeing this behaviour on

  • OS: Linux
  • Redis:5.0.7
  • PHP:7.4.26
  • phpredis:5.3.7

Steps to reproduce, backtrace or example script

$reflection = new \ReflectionClass(\Redis::class);
$method = $reflection->getMethod("sPop");
print_r($method->getParameters());

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Expected behaviour

As per hScan documentation, the function should always return an array.

Actual behaviour

It is observed that the method returns false when the hash doesn't have anything set, which makes sense.

Further to this, phpstan and probably the php compiler recognises that this hScan function should only return an array. The method return signature in the extension is probably defining this.

I'm seeing this behaviour on

  • OS: Linux
  • Redis: 6.0.10
  • PHP: 7.4.14
  • phpredis: 5.3.2

Steps to reproduce, backtrace or example script

<?php

$r = new \Redis();
$r->connect('127.0.0.1');
$r->setOption(Redis::OPT_SCAN, Redis::SCAN_RETRY);
$r->hSet('abc123', 'myfield', 'myvalue');

$it = null;

print 'Test #1:' . PHP_EOL;
var_dump($r->hScan('myfield', $it));

print PHP_EOL;

print 'Test #2:' . PHP_EOL;
var_dump($r->hScan('myfield2', $it));

$r->close();

OUTPUT:

Test #1:
array(0) {
}

Test #2:
bool(false)

I've checked

  • ๐Ÿ‘ There is no similar issue from other users
  • ๐Ÿ‘ Issue isn't fixed in develop branch

Final note

The fix for this can either be as per documentation or to fix the method signature to correctly state the returning of FALSE as an option. Either way works for me.

NOTE: This might also be a regression fixed in dev-master

* Fix regression for conntecting to ports > 32767 [1f41da64] (Owen Smith)

Expected behaviour

- *port*: int, optional
+ *port*: int, optional. Set this to null/0 for unix socket paths starting with / if you need to pass other parameters

https://github.com/phpredis/phpredis#connect-open

Actual behaviour

Examples only exist with TCP. There's no explicit documentation of what port you should pass alongside a unix socket if you want to pass a timeout.

I'm seeing this behaviour on

  • OS: Linux
  • Redis: N/A
  • PHP: 7.2
  • phpredis: 5.1.0RC2 - I see that there's a fix added to Redis::CONNECT to convert negative ports to 0.

Steps to reproduce, backtrace or example script

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch (Documentation isn't clear on develop, but the bug may have been fixed)

What was the intent of a080b73f ?

Would the following change make more sense instead?

-     if (address[0] == '/' && redis_sock->port < 1) {
+     if (address[0] == '/' || redis_sock->port < 1) {

Expected behaviour

Release information provided for this project at https://api.github.com/repos/phpredis/phpredis/releases/latest, similar to https://api.github.com/repos/php-memcached-dev/php-memcached/releases/latest and https://api.github.com/repos/igbinary/igbinary/releases/latest.

For more info, refer to https://developer.github.com/v3/repos/releases/#get-the-latest-release

Actual behaviour

I get a Not Found error message.

I'm seeing this behaviour on

  • OS: n/a
  • Redis: n/a
  • PHP: n/a
  • phpredis: n/a

Steps to reproduce, backtrace or example script

See above.

I've checked

  • [x ] There is no similar issue from other users
  • [x ] Issue isn't fixed in develop branch

Expected behaviour

Redis::keys should always return an array according to documentation.

Actual behaviour

It seems it returns false in some cases according to the trace we get here:
nextcloud/server#34155

I'm seeing this behaviour on

  • OS: Ubuntu 22.04
  • Redis:
  • PHP: php 8.1
  • phpredis:

Steps to reproduce, backtrace or example script

See nextcloud/server#34155

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Expected behaviour

No PhpAllowedMemorySizeReachedError

Actual behaviour

Rarely PhpAllowedMemorySizeReachedError

I'm seeing this behaviour on

  • OS: Red Hat Enterprise Linux release 8.6 (Ootpa)
  • Redis: redis-5.0.3-2.module_el8.2.0+318+3d7e67ea.x86_64
  • PHP: 7.4.30
  • phpredis: php74-php-pecl-redis5-5.3.7-1.el8.remi.x86_64

Steps to reproduce, backtrace or example script

Can't reproduce, occurs rarely

We have been stumped for years of the following PhpAllowedMemorySizeReachedError
error that shows up in our PHP profiler.
We can't imagine any scenario where this can occur normally(even with bad code), without a bug in the underlying session module or PHP itself.

Here is capture of the PhpAllowedMemorySizeReachedError error that rarely shows up in our PHP profiler:
memory_profiler

Here is the related code:
php_code

$this_document_srl is a number.
$max_ssession_count is 100

phpredis config information:
image

session config infromation:
session

php-fpm setup information:
session.save_handler = redis
session.save_path = "tcp://[IPREDACTED]:6379?persistent=1&weight=1&timeout=3"

We also have put the following logging debug code before the related code to check if we have bad code causing memory leaks.
$sessionsize = strlen(serialize($_SESSION));
if($sessionsize > 100000) {
---- LOGGING CODE ----
}
and nothing is logged.

We suspect possible memory leak, serialize bug or other bug in phpredis.
Any thoughts?

I've checked

  • [ O ] There is no similar issue from other users
  • [ X ] Issue isn't fixed in develop branch

Thank you.

Yesterday we have deployed by mistake phpredis 6.0.0-dev to one of our production clusters. A couple of seconds later the whole cluster started to throw Redis timeouts and connection refused. Reducing the load of the cluster reduced the issue but didn't solved it.

Reverting back to 5.3.7 solved the issue right away. We have 3 different pconnects to 3 different Redis Servers. 2 of them are 6.0.5 and 1 is 6.2.5

It's AWS specific but might be related to the root cause. 2 of our Redis servers are Elasticache instances and they started throwing "Network Connections tracked Allowance Exceeded". The 3rd Redis is a standalone server and was not showing this behaviour / error but same result with random Timeouts. The rate of timeouts varies depending on the "traffic". It starts with <1% on low traffic and got to 99% on high load/traffic.

Since the issue is "load" related and not easy to reproduce in test environment i'm reporting this issue also against a dev version.

We have "redis.pconnect.echo_check_liveness=0" as only difference to default setup

We tried as well to replace pconnect with connect and it solved the issue on 6.0.0-dev, but it's overloading our Redis servers.

Expected behaviour

a stable connection with no Timeouts / Redis excetions

Actual behaviour

PHP Fatal error: Uncaught RedisException on random requests when using pconnect.

I'm seeing this behaviour on

  • OS: Linux 4.14.287-215.504.amzn2.aarch64 #1 SMP Wed Jul 13 21:34:37 UTC 2022 aarch64 aarch64 aarch64 GNU/Linux
  • Redis: 6.0.5 and 6.2.5
  • PHP: PHP 8.1.8 (cli) (built: Jul 25 2022 21:19:09) (ZTS)
    Copyright (c) The PHP Group
    Zend Engine v4.1.8, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.8, Copyright (c), by Zend Technologies
  • phpredis: 6.0.0-dev and 5.3.7

Steps to reproduce, backtrace or example script

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Expected behaviour

Actual behaviour

I'm seeing this behaviour on

  • OS: Ubuntu 16.04.5 LTS
  • Redis: 5.0.4 (from ppa)
  • PHP: 7.2.14
  • phpredis: 4.2.0-1+ubuntu16.04.1+deb.sury.org+1

Steps to reproduce, backtrace or example script

  • hit an issue during Nextcloud setup with Redis-cache-cluster.
    -I always get the error message "Couldn't map cluster keyspace using any provided seed "
    -directly connecting to the Redis-cache cluster works however

redis-cli -p 13000 -a cluster nodes
-> shows all nodes

I've checked

  • There is no similar issue from other users
    -> there are other users who report similar issues, but no solutions/fixes etc. exist

Cheers
Thomy

From RELEASENOTES

New commands / args:

  • Add SMISMEMBER command that checks multiple members (#7615)
  • Add ZMSCORE command that returns an array of scores (#7593)
  • Add LMOVE and BLMOVE commands that pop and push arbitrarily (#6929)
  • Add RESET command that resets client connection state(#7982)
  • Add COPY command that copies keys (#7953)
  • Add ZDIFF and ZDIFFSTORE commands (#7961)
  • Add ZINTER and ZUNION commands (#7794)
  • Add GEOSEARCH/GEOSEARCHSTORE commands for bounding box spatial queries (#8094)
  • Add GET parameter to SET command, for more powerful GETSET (#7852)
  • Add exclusive range query to XPENDING (#8130)
  • Add exclusive range query to X[REV]RANGE (#8072)
  • Add GT and LT options to ZADD for conditional score updates (#7818)
  • Add CLIENT INFO and CLIENT LIST for specific ids (#8113)
  • Add IDLE argument to XPENDING command (#7972)
  • Add local address to CLIENT LIST, and a CLIENT KILL filter. (#7913)
  • Add NOMKSTREAM option to XADD command (#7910)
  • Add command introspection to Sentinel (#7940)
  • Add SENTINEL MYID subcommand (#7858)

From 6.2RC2

  • Add the REV, BYLEX and BYSCORE arguments to ZRANGE, and the ZRANGESTORE command (#7844)
  • Add the XAUTOCLAIM command (#7973)
  • Add the MINID trimming strategy and the LIMIT argument to XADD and XTRIM (#8169)
  • Add the ANY argument to GEOSEARCH and GEORADIUS (#8259)
  • Add the CH, NX, XX arguments to GEOADD (#8227)
  • Add the COUNT argument to LPOP and RPOP (#8179)
  • Add the WRITE argument to CLIENT PAUSE for pausing write commands exclusively (#8170)
  • Change the proto-ver argument of HELLO to optional (#7377)
  • Add the CLIENT TRACKINGINFO subcommand (#7309)

From 6.2RC3

  • Add HRANDFIELD and ZRANDMEMBER commands (#8297)
  • Add FAILOVER command (#8315)
  • Add GETEX, GETDEL commands (#8327)
  • Add PXAT/EXAT arguments to SET command (#8327)
  • Add SYNC arg to FLUSHALL and FLUSHDB, and ASYNC/SYNC arg to SCRIPT FLUSH (#8258)

Hi,

After upgrading to PHP 7.4 has been appeared a problem with random auth() freezing.
The same script executed with php 7.3.15 (with same phpredis version) works fine.
It seems that execution is stopped until server-side TCP keepalive timeout reached.
As there are the same phpredis versions, I'm not sure that it is a phpredis issue. But maybe somebody can help in future investigation.
But it seems strange that read timeout option does not affects the auth call.

Expected behaviour

auth() should throw read timeout exception after 5 seconds

Actual behaviour

execution stopped for 300 seconds until TCP keepalive timeout reached

I'm seeing this behaviour on

  • OS: Ubuntu 18.04.4 LTS
  • Redis: 5.0.6 (digitalocean managed instance)
  • PHP: 7.4.3
  • phpredis: 5.2.0

Steps to reproduce, backtrace or example script

example script:

<?php

function l($message)
{
    global $current;
    echo $message . ' (' . (microtime(true) - $current) . ')' . PHP_EOL;
    $current = microtime(true);
}

ini_set('default_socket_timeout', 5);

$start = microtime(true);
$current = microtime(true);

l('start');
$redis = new Redis();
if (!$redis->connect('tls://redis-instance', 25061, 5, null, 5, 5)) {
    throw new RuntimeException($redis->getLastError());
}
l('connected');
$redis->setOption(Redis::OPT_READ_TIMEOUT, 5);
l('option is set');
$redis->auth('some-password');
l('auth complete');
$redis->select(4);
l('db selected');

echo 'Total: ' . (microtime(true) - $start) . PHP_EOL;

occasionally this script hangs up for 300 seconds:

user:~$ while true; do php redis.php; done
start (5.9604644775391E-6)
connected (0.017167091369629)
option is set (5.0067901611328E-6)
auth complete (0.00058794021606445)
db selected (0.00032281875610352)
Total: 0.018187999725342
start (4.0531158447266E-6)
connected (0.012931108474731)
option is set (7.1525573730469E-6)
auth complete (0.00078892707824707)
db selected (0.00040698051452637)
Total: 0.014256000518799
start (4.0531158447266E-6)
connected (0.01163911819458)
option is set (1.0967254638672E-5)
auth complete (300.07370495796)
db selected (0.00037598609924316)
Total: 300.08729100227

strace log:

write(3, "\27\3\3\0006[O\21\240\275|H\243\356\344\16\277\215\243\362h;\350*<N@\24\25\225\254["..., 59) = 59
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
read(3, "\27\3\3\0\26", 5)              = 5
read(3, "\262\341\277k3\317O\3143X\232\313\310\2742\246\v\203\341\332T\261", 22) = 22
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
write(1, "2020-03-17 10:49:05 auth complet"..., 522020-03-17 10:49:05 auth complete (300.79558706284)
) = 52
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
write(3, "\27\3\3\0(\245\360\223\217\252\375p\311\324\246\323\1\303\243\360\343\302\2:\214\5'\"\224\32\2500"..., 45) = 45
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
poll([{fd=3, events=POLLIN|POLLPRI|POLLERR|POLLHUP}], 1, 0) = 0 (Timeout)
fcntl(3, F_GETFL)                       = 0x2 (flags O_RDWR)
fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK)    = 0
read(3, "\27\3\3\0\26", 5)              = 5
read(3, "\327n\353\321\367\354\317[\274&\316)\237C\304\305\275\343\4\266\334\10", 22) = 22
fcntl(3, F_GETFL)                       = 0x802 (flags O_RDWR|O_NONBLOCK)
fcntl(3, F_SETFL, O_RDWR)               = 0
write(1, "2020-03-17 10:49:05 db selected "..., 542020-03-17 10:49:05 db selected (0.00063395500183105)

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Hello!

We are not quite sure whether any issues exists or we just simply use RedisSentinel incorrectly. So plz correct us if our assumptions about RedisSentinel behaviour are incorrect.

Expected behaviour

We have three sentinel servers. We instantiate RedisSentinel in our web application and specify "persistent" parameter in constructor. We expect that some limited pool of persistent connections will be produced and one connection from this pool will be used for each new incoming http request.

Actual behaviour

However, during the tests we saw that new connection was established for each new http request. As a result, we ran out of free tcp sockets within a couple of seconds.

I'm seeing this behaviour on

  • OS: CentOS 7
  • Redis: 7.0.0
  • PHP: 8.1.2
  • phpredis: 5.3.6

Steps to reproduce, backtrace or example script

  try {
      $sentinel = new \RedisSentinel($sentinel[0], $sentinel[1], 1, 'sentinel', 100, 1);
  } catch (\RedisException $e) {
     return [];
  }

  $masterInfo = $sentinel->master('mymaster');
  if (!$masterInfo) {
      return [];
  }
  return [$masterInfo['ip'], (int)$masterInfo['port']];

Expected behaviour

If I've understood the docs correctly, something like the following...

$sentinel = new RedisSentinel('redis-sentinel', 26379, 0, 'persistent_sentinel');

...should result in a persistent connection to the redis-sentinel server (similar to a pconnect being used with redis).

Actual behaviour

A new connection is being created to the redis-sentinel server in each http req/res cycle.

I'm seeing this behaviour on

  • OS: Debian GNU/Linux 10 (buster) -- inside a docker container
  • Redis: bitnami/redis:7.0 (docker)
  • PHP: webdevops/php-nginx:7.3 (docker)
  • phpredis: 5.3.7

Steps to reproduce, backtrace or example script

<?php
$sentinel = new RedisSentinel('redis-sentinel', 26379, 0, 'persistent_sentinel');
echo "master:\n";
$master = $sentinel->master('mymaster');
print_r($master['ip']);
echo "=====\n";
?>

I've checked

  • There is no similar issue from other users

Actually there is #2110 but I do not know how to reopen it and continue the conversation there itself.

  • Issue isn't fixed in develop branch

How do I install the develop branch via pecl?

Expected behaviour

Persist user sessions to Redis.

Actual behaviour

This is using Redis 6 on StackHero, which works perfectly:

        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', "tls://[HOST].stackhero-network.com:6380?auth=[PASSWORD]");

This is using Redis 6 on Heroku, which causes the error below:

        ini_set('session.save_handler', 'redis');
        ini_set('session.save_path', "tls://[HOST].eu-west-1.compute.amazonaws.com:21070?auth=[PASSWORD]");

Error message:

Warning: session_start(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed in /var/www/application/core/Session.php on line 19
Warning: session_start(): Failed to read session data: redis (path: tls://[HOST].eu-west-1.compute.amazonaws.com:21070?auth=[PASSWORD]) in /var/www/application/core/Session.php on line 19

I'm pretty certain it's down to Heroku Redis being self-signed certificates, but I'm not sure how to disable certificate verification / whether that's the right approach.

Thanks in advance for any pointers.

I'm seeing this behaviour on

  • OS: Heroku-20
  • Redis: 6
  • PHP: 7.4
  • phpredis: 5.3

Steps to reproduce, backtrace or example script

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Expected behaviour

PHP Redis to work as an interface between Redis and PHP.

Actual behaviour

Segmentation fault (core dumped)

I'm seeing this behaviour on

  • OS: CentOS Linux release 8.5.2111
  • Redis: 7.0.0
  • PHP: 8.1.5
  • phpredis: 5.3.7

Steps to reproduce, backtrace or example script

This seg-faults

<?php
$redis = new RedisCluster(NULL, Array('node_1_ip:6379','node_2_ip:6379','node_3_ip:6379'), 2.5, 2.5, true, 'password');
$redis->set('test','value');

This works fine

<?php
$redis->connect('node_1_ip',6379);
$redis->set('test','value');

I've checked

  • There is no similar issue from other users
  • [YES] Issue isn't fixed in develop branch -> Doesnt work in develop branch as well.

For now, it seems I have to downgrade Redis to 6.2 to make it work

Expected behaviour

The following should work in php-fpm.conf:

php_admin_value[session.save_handler] = redis
php_admin_value[session.save_path] = "tls1.2://127.0.0.1:6379?stream[verify_peer_name]=0&stream[cafile]=file:///etc/pki/redis/ca.crt"

Actual behaviour

After the start of php-fpm and first request for anything doing session_start() php-fpm fails and dies totally.

# /usr/sbin/php-fpm8.0 -F -y /etc/php/8.0/fpm/php-fpm.conf
[09-Aug-2022 19:18:07] NOTICE: fpm is running, pid 23984
[09-Aug-2022 19:18:07] NOTICE: ready to handle connections
[09-Aug-2022 19:18:07] NOTICE: systemd monitor interval set to 10000ms
[09-Aug-2022 19:18:13] WARNING: [pool www] child 23986 exited on signal 11 (SIGSEGV) after 5.321825 seconds from start
[09-Aug-2022 19:18:13] NOTICE: [pool www] child 23987 started

I'm seeing this behaviour on

  • OS: Ubuntu 20.04 LTS in WSL2
  • Redis: Redis server v=7.0.3 sha=00000000:0 malloc=libc bits=64 build=78de1e2aecbd405
  • PHP: PHP 8.0.21 (cli) (built: Aug 1 2022 07:40:52) ( NTS )
  • phpredis: 6.0.0-dev

Steps to reproduce, backtrace or example script

Minimal script used:

<?php

session_start();
echo('ok');

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Expected behaviour

Always return true, as specified in Doc

Actual behaviour

Sometimes returns false

I'm seeing this behaviour on

  • OS: Ubuntu 18.04.6 LTS
  • Redis: 6.0.6
  • PHP: 8.0.17
  • phpredis: 6.0.0-dev

Steps to reproduce, backtrace or example script

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Is it time to enable hset to take associative array as second paramter and if redis server is below 4.0 fallback to hmset? Or is it better to have hmset actually call a varadic hset if redis server is above 4.0

Expected behaviour

PHP to store sessions on redis

Actual behaviour

Sessions are not stored.

I'm seeing this behaviour on

  • OS: Ubuntu 20.04.4 LTS
  • Redis: 5.0.6
  • PHP: 8.1.7
  • phpredis: 5.3.7

Steps to reproduce, backtrace or example script

Right after a session_start()I get the following error

Warning: session_start(): Failed to read session data: redis (path: tcp://******.cache.amazonaws.com:6379?auth=) in db_init.php on line 20

I've checked

  • There is no similar issue from other users
  • Issue isn't fixed in develop branch

Thanks!