We noticed a breaking change after upgrading from 6.2.0 to 6.3.0. When passing strings containing leading zeros (e.g., "0123") to hmget or mget, phpredis 6.3.0 seems to cast them to integers (123) internally before sending the command to Redis.
Since Redis keys are binary safe strings, "0123" is not equal to "123", resulting in cache misses (returning false or empty data) for existing keys.
Attempted Workarounds:
We tried to mitigate this behavior by explicitly setting various options, but none of them restored the 6.2.0 behavior. The issue persists regardless of:
Redis::OPT_SERIALIZER (NONE or PHP)
Redis::OPT_PREFIX
Redis::OPT_PACK_IGNORE_NUMBERS (where available)
It appears the argument parsing casts the key before these options are even evaluated.
Reproducible Code:
A minimal example demonstrating the issue:
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
// Setup data
$key = 'test_hash';
$field = '0123'; // String with leading zero
$redis->hSet($key, $field, 'value_found');
// Test in 6.3.0
$result = $redis->hMGet($key, [$field]);
// Expected (Behavior in 6.2.0):
// array('0123' => 'value_found')
// Actual (Behavior in 6.3.0):
// array('0123' => false)
// (Presumably because it queried for integer 123)
Environment:
- PHP Version: 8.2.30
- Phpredis Version: 6.3.0
- Redis Version: 7
Full Reproduction Environment:
I have attached a ZIP file containing a Docker environment (docker-compose.yml, Dockerfile, and a test script) that compares 6.2.0 and 6.3.0 side-by-side to prove the regression.
(Please see attached repro-issue.zip)
To test it call docker-compose exec php-620 php repro.php resp. docker-compose exec php-620 php repro.php
Outputs:
docker-compose exec php-620 php repro.php
--- Environment Check ---
PHP Version: 8.2.30
PhpRedis Extension Version: 6.2.0
--- Setup Phase ---
Data prepared: HSET user:data '0123' 'Value for Key 0123'
-------------------------------------------------------
--- Starting Tests (New Connection per Test) ---
Testing: 1. Default (No Options) ... ✅ PASS
Testing: 2. OPT_SERIALIZER = NONE ... ✅ PASS
Testing: 3. OPT_SERIALIZER = PHP ... ✅ PASS
Testing: 4. OPT_PREFIX = "" ... ✅ PASS
Testing: 5. OPT_NULL_MULTIBULK_AS_NULL = true ... ✅ PASS
Testing: 6. OPT_PACK_IGNORE_NUMBERS = true ... ✅ PASS
-------------------------------------------------------
docker-compose exec php-620 php repro.php
--- Environment Check ---
PHP Version: 8.2.30
PhpRedis Extension Version: 6.3.0
--- Setup Phase ---
Data prepared: HSET user:data '0123' 'Value for Key 0123'
-------------------------------------------------------
--- Starting Tests (New Connection per Test) ---
Testing: 1. Default (No Options) ... ❌ FAIL [Array(Key: '123' [integer])]
Testing: 2. OPT_SERIALIZER = NONE ... ❌ FAIL [Array(Key: '123' [integer])]
Testing: 3. OPT_SERIALIZER = PHP ... ❌ FAIL [Array(Key: '123' [integer])]
Testing: 4. OPT_PREFIX = "" ... ❌ FAIL [Array(Key: '123' [integer])]
Testing: 5. OPT_NULL_MULTIBULK_AS_NULL = true ... ❌ FAIL [Array(Key: '123' [integer])]
Testing: 6. OPT_PACK_IGNORE_NUMBERS = true ... ❌ FAIL [Array(Key: '123' [integer])]
-------------------------------------------------------
We noticed a breaking change after upgrading from
6.2.0to6.3.0. When passing strings containing leading zeros (e.g.,"0123") tohmgetormget, phpredis6.3.0seems to cast them to integers (123) internally before sending the command to Redis.Since Redis keys are binary safe strings,
"0123"is not equal to"123", resulting in cache misses (returningfalseor empty data) for existing keys.Attempted Workarounds:
We tried to mitigate this behavior by explicitly setting various options, but none of them restored the
6.2.0behavior. The issue persists regardless of:Redis::OPT_SERIALIZER(NONE or PHP)Redis::OPT_PREFIXRedis::OPT_PACK_IGNORE_NUMBERS(where available)It appears the argument parsing casts the key before these options are even evaluated.
Reproducible Code:
A minimal example demonstrating the issue:
Environment:
Full Reproduction Environment:
I have attached a ZIP file containing a Docker environment (docker-compose.yml, Dockerfile, and a test script) that compares 6.2.0 and 6.3.0 side-by-side to prove the regression.
(Please see attached repro-issue.zip)
To test it call
docker-compose exec php-620 php repro.phpresp.docker-compose exec php-620 php repro.phpOutputs: