Skip to content

[Regression 6.3.0] hmget/mget casts numeric strings with leading zeros to integer #2795

@Bezkeroon

Description

@Bezkeroon

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])]
-------------------------------------------------------

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions