Skip to content

Conversation

@gnutix
Copy link
Contributor

@gnutix gnutix commented Feb 2, 2026

🤖 Generated by Claude Code

Fixes phpstan/phpstan#8636 (which has happened on our project too)

Summary

  • Add new configuration parameter constantArrayTypeBuilderArrayCountLimit that allows users to customize the array count limit
  • Default value remains 256 (current behavior)
  • Follow the existing BleedingEdgeToggle pattern with a static accessor class
  • Keep the original constant for backward compatibility (marked as deprecated)

Usage

Users can configure the limit in their phpstan.neon:

parameters:
    constantArrayTypeBuilderArrayCountLimit: 512

Test plan

  • Unit tests pass: vendor/bin/phpunit tests/PHPStan/Type/Constant/ConstantArrayTypeBuilderTest.php (7 tests, 41 assertions)
  • Syntax validation: All modified files pass php -l syntax check
  • Manual verification with test script demonstrating the feature:
<?php
use PHPStan\DependencyInjection\ConstantArrayTypeLimitAccessor;
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
use PHPStan\Type\Constant\ConstantStringType;

// Build array with 300 elements
$builder = ConstantArrayTypeBuilder::createEmpty();
for ($i = 0; $i < 300; $i++) {
    $builder->setOffsetValueType(new ConstantStringType("key_$i"), new ConstantStringType("value_$i"));
}

// With default limit (256): array is degraded
$type = $builder->getArray();
// Result: PHPStan\Type\IntersectionType (degraded)

// With increased limit (512): array is tracked precisely
ConstantArrayTypeLimitAccessor::setLimit(512);
$builder2 = ConstantArrayTypeBuilder::createEmpty();
for ($i = 0; $i < 300; $i++) {
    $builder2->setOffsetValueType(new ConstantStringType("key_$i"), new ConstantStringType("value_$i"));
}
$type2 = $builder2->getArray();
// Result: PHPStan\Type\Constant\ConstantArrayType with 300 keys (precise)

Test results:

Array Size Limit Result
200 256 ✓ Precise (ConstantArrayType)
300 256 ✗ Degraded (IntersectionType)
300 512 ✓ Precise (ConstantArrayType)
600 512 ✗ Degraded (IntersectionType)

Add new configuration parameter `constantArrayTypeBuilderArrayCountLimit`
that allows users to customize the array count limit (default: 256).

This follows the existing BleedingEdgeToggle pattern with a static accessor.
The original constant is kept for backward compatibility but marked deprecated.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@staabm
Copy link
Contributor

staabm commented Feb 2, 2026

you should measure the perf impact when using different values for this limit, as it could get very slow depending on your code

@ondrejmirtes
Copy link
Member

Hi, I disagree with this solution. I don't want to let people shoot themselves in the foot by slowing down PHPStan.

The right solution to this problem is to improve ConstantArrayType performance so we can raise the limit.

If you have some examples where the current limit limits you, please open issues about them and we'll try to make the limit higher by making PHPStan faster.

@gnutix
Copy link
Contributor Author

gnutix commented Feb 3, 2026

I understand this option should not be used lightly ; but it seems better to me to have a working analysis that is slow-er than a broken analysis that is fast, for people that do hit that limit for critical pieces of their codebase (in our application, we have a ConfigKey enum with 200+ configs that change the way the application behaves in different modules, and a PHP array that stores for each config its default value, its type, authorizations, the module its linked to, etc.). So that array is bound to grow forever more, so even if you increase that limit to 350, someday in the future, we'll reach it. For now, we've managed to avoid that hard-coded limit by splitting the array in multiple sub-arrays per-module, and it's working for this one. But we have other arrays that we know already will cause us trouble soon-ish.

And I'm all for "making PHPStan faster" (surely it benefits everyone, so that's a huge win), but what I see is that you are already doing an amazing job at this and constantly improving the performances, so I don't know what more could be done "specifically for this issue". And yet, I wonder why this hard-coded value was never changed then ? What kind of benchmarks would be needed to check that's the current value is still the "optimal one" with today's PHPStan's performances ?

@ondrejmirtes
Copy link
Member

I just want to see a source code that's impacted by the current limit. We can increase the limit so that the array is not degraded & watch Blackfire performance profiles to see what could be optimized.

@staabm
Copy link
Contributor

staabm commented Feb 3, 2026

I just want to see a source code that's impacted by the current limit. We can increase the limit so that the array is not degraded & watch Blackfire performance profiles to see what could be optimized.

yes, I am also interessted in the examples.

I already had a look at existing tests and profiles suggested that

  • we can bump to limit=512 without perf difference in AnalyzerIntegrationTest
  • speed up TrinaryLogic #4833 will improve one of the existing cases a few %

@gnutix
Copy link
Contributor Author

gnutix commented Feb 3, 2026

Unfortunately, the project I'm working on cannot be shared publicly (though to give you an idea, it's ~549k lines of PHP code, which we split in two with different PHPStan configs : legacy got ~183k and new code ~366k). And I guess you need "the whole codebase" to judge if the PHPStan complete analysis is X% or Y% slower when raising that limit ? So extracting just this array, anonymizing its data, wouldn't really help you, right ?

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.

Oversimplified huge const array

3 participants