Skip to content

Fix phpstan/phpstan#4296: BleedingEdge: Offset '1234' on array<string, Test>&nonEmpty in isset() does not exist.#5148

Closed
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-y9vved1
Closed

Fix phpstan/phpstan#4296: BleedingEdge: Offset '1234' on array<string, Test>&nonEmpty in isset() does not exist.#5148
phpstan-bot wants to merge 1 commit intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-y9vved1

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Summary

When using isset($map[$value]) on an array<string, Test> where $value is a numeric string like '1234', PHPStan incorrectly reports "Offset '1234' does not exist." This is a false positive because the array has string keys and '1234' is a valid string.

Changes

  • Modified ArrayType::hasOffsetValueType() in src/Type/ArrayType.php to also check the original (pre-coercion) offset type against the key type
  • Applied the same fix to ArrayType::getOffsetValueType() for consistency
  • Added regression test in tests/PHPStan/Rules/Variables/data/bug-4296.php
  • Added test method testBug4296() in tests/PHPStan/Rules/Variables/IssetRuleTest.php

Root cause

ConstantStringType('1234')->toArrayKey() converts numeric strings to ConstantIntegerType(1234) (matching PHP's array key coercion behavior). Then ArrayType::hasOffsetValueType() checks if the key type (StringType) is a supertype of the coerced offset type (ConstantIntegerType), which returns no. The existing guard condition only checks if the coerced type is a non-constant string — it doesn't account for the case where the original type was a string that got coerced to an integer. The fix adds an additional check against the original offset type before returning no.

Test

Added a regression test that reproduces the exact scenario from the issue: building an array<string, Test> in a loop using string keys from getId(), then checking with isset($map[$value]) where $value is the numeric string '1234'. The test expects no errors.

Fixes phpstan/phpstan#4296

…ng offset on string-keyed array

- In ArrayType::hasOffsetValueType() and getOffsetValueType(), numeric string offsets
  like '1234' are converted to integers by toArrayKey(), then rejected because
  IntegerType is not a supertype of StringType key
- Added check against original (pre-coercion) offset type so numeric strings are
  recognized as valid string keys
- New regression test in tests/PHPStan/Rules/Variables/data/bug-4296.php
@staabm staabm deleted the create-pull-request/patch-y9vved1 branch March 8, 2026 11:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants