Skip to content

Fix phpstan/phpstan#14312: Parameter #2 of array_key_exists expects array, non-empty-array given#5237

Merged
staabm merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-n2succo
Mar 17, 2026
Merged

Fix phpstan/phpstan#14312: Parameter #2 of array_key_exists expects array, non-empty-array given#5237
staabm merged 4 commits intophpstan:2.1.xfrom
phpstan-bot:create-pull-request/patch-n2succo

Conversation

@phpstan-bot
Copy link
Copy Markdown
Collaborator

Summary

When a mixed variable was narrowed to non-empty-array via array_key_exists() with a non-constant key, a subsequent array_key_exists() call on the same variable would report a false positive: "Parameter #2 $array of function array_key_exists expects array, non-empty-array given."

Changes

  • Modified src/Type/Php/ArrayKeyExistsFunctionTypeSpecifyingExtension.php to include ArrayType(mixed, mixed) in the narrowing type when the variable is not already an array type
  • Added regression test in tests/PHPStan/Rules/Functions/data/bug-14312.php and tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Root cause

The ArrayKeyExistsFunctionTypeSpecifyingExtension narrowed non-constant key cases to a standalone NonEmptyArrayType accessory type. When intersected with mixed (the original type), the result was a standalone NonEmptyArrayType — an incomplete type that lacked the underlying ArrayType. This standalone accessory type was not recognized as a valid array subtype by ArrayType::accepts(), causing the false positive.

The fix conditionally includes ArrayType(mixed, mixed) in the narrowing type only when the variable is not already an array (to avoid interfering with existing key type refinements like subtracted types). This produces a proper array<mixed, mixed> & non-empty-array intersection type that is correctly accepted by array parameters.

Test

Added a rule test that verifies no error is reported when array_key_exists() is called on a variable already narrowed to non-empty-array by a prior array_key_exists() call.

Fixes phpstan/phpstan#14312

… not accepted as array

- Fixed ArrayKeyExistsFunctionTypeSpecifyingExtension to include ArrayType
  in the narrowing type when the variable is not already an array type
- When mixed is narrowed via array_key_exists with a non-constant key, the
  type now becomes array<mixed, mixed> & non-empty-array instead of standalone
  non-empty-array, which is properly accepted by the array parameter type
- Added regression test in tests/PHPStan/Rules/Functions/data/bug-14312.php
Copy link
Copy Markdown
Contributor

@staabm staabm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check whether we have a similar problem in other *TypeSpecifyingExtension classes.
try to come up with a failling unit test. if you find a failling test add a fix.

…SpecifyingExtension

Apply the same fix from ArrayKeyExistsFunctionTypeSpecifyingExtension:
when the variable is not already an array type, include ArrayType(mixed, mixed)
in the intersection to produce a proper array & non-empty-array type.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@phpstan-bot
Copy link
Copy Markdown
Collaborator Author

Already retrieved — static analysis passed with no errors. Everything is green and pushed.

@staabm staabm requested a review from VincentLanglet March 17, 2026 15:55
@VincentLanglet VincentLanglet requested a review from staabm March 17, 2026 16:02
@phpstan-bot
Copy link
Copy Markdown
Collaborator Author

Already retrieved — all 11,584 tests passed. Everything is green, nothing more to do.

@staabm staabm merged commit dd498a5 into phpstan:2.1.x Mar 17, 2026
652 checks passed
@staabm staabm deleted the create-pull-request/patch-n2succo branch March 17, 2026 16:08
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.

3 participants