Skip to content

Releases: phpstan/phpstan

2.3.1

Choose a tag to compare

@phpstan-bot phpstan-bot released this 08 Oct 21:10
Immutable release. Only release title and notes can be modified.
6155239

Same performance, smaller package

We've heard your feedback. PHPStan 2.3.0 was chonky! It weighed 104 MB when downloaded and 268 MB after being unzipped in your vendor/.

Afer #6703, PHPStan 2.3.1 weighs just under 28 MB when downloaded and 87 MB unzipped.

Improvements 🔧

  • Ship the turbo extension as a shared core plus a thin extension per PHP version (#6703), #15423
  • Build Linux ZTS turbo binaries for PHP 8.3-8.5 too (#6706), #15422
  • Allow PHP 8.6 in phpstan/turbo (Composer PIE package) (#6705)

Bugfixes 🐛

Performance 🏎️

  • Check original type for unresolvable types only when resolved type has one (#6675), thanks @Kocal!
  • Keep the restored result cache out of forked workers' memory (#6686), #15387, thanks @janedbal!
  • Save the result cache when a file has a parse error (#6694), thanks @SanderMuller!

Internals 🔍

  • Start the cold run of the warm-rewrite test in a new second (#6697), thanks @SanderMuller!

2.3.0

Choose a tag to compare

@phpstan-bot phpstan-bot released this 06 Oct 06:33
Immutable release. Only release title and notes can be modified.
b1f9890

This release fixes a whopping 75 issues! 🚀

Read about PHPStan 2.3.0 on the blog » I promise it's worth checking it out yourself, and not just letting your agent summarize it for you 😉 It contains a lot of interactive widgets with practical examples of the new features in action.

Major leap in performance. Back in December 2025 with PHPStan 2.1.33, as an example, analysing WordPress core took 60 seconds. With today's PHPStan 2.3.0, it takes under 8 seconds. Similar performance speedups can be observed across many codebases.

phpstan-2-3-performance

PHPStan Turbo speeds up PHPStan by 60% over the no-Turbo baseline.

Bleeding edge 🔪

If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:

includes:
	- vendor/phpstan/phpstan/conf/bleedingEdge.neon

Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more

Improvements 🔧

Bugfixes 🐛

  • Keep property fetches on the receiver when a static method or static closure invalidates it (#6391), #13735, thanks @staabm and @SanderMuller
  • Derive conditional guard types from the branch set difference (#6380), #13833, #9685, #7706, #14421
  • Build a loop's back edge from its continue statements when the body end is unreachable (#6420), #14418, #13959, #11919, #1946
  • Widen only the variables a loop can write when its scope converges (#6421), #12666
  • Infer closure parameter types in array arguments (#6422), #6430, #11215
  • Resolve generic parameter types from an array literal argument's skeleton before typing the closures nested in it (#6482), #15269
  • Preserve conditional expression holders across more scope merges (#6385), #9628, #6830
  • Narrow optional array offsets through isset() conditions (#6382), #9426, #6379, #12786
  • Do not read PHP_SBINDIR and PHP_BUILD_PROVIDER off the analysing machine (#6454), thanks @SanderMuller!
  • Honour the composer.json require.php constraint in Scope::getPhpVersion() (#6476), #15270, thanks @staabm and @VincentLanglet!
  • Skip @phpstan-assert, conditional return types and call effects when the nullsafe chain may short-circuit (#6486), #15016, #12925, thanks @VincentLanglet and @staabm!
  • NativeTypedClassConstantRule is scope php-version aware (#6497), #13133, thanks @staabm!
  • Keep never in MutatingScope::intersectButNotNever() instead of widening it to null (#6504), #15285
  • Resolve "supported only on PHP X" checks from Scope::getPhpVersion() instead of the injected PhpVersion (#6496), #13133, thanks @staabm and @VincentLanglet!
  • Resolve property, trait constant, arrow function never and attribute PHP version checks from Scope::getPhpVersion() (#6510), #13133, thanks @staabm and @VincentLanglet!
  • Resolve the printf format parser's PHP version check from Scope::getPhpVersion() (#6536), thanks @staabm!
  • Resolve PHP version checks in src/Type/Php extensions from Scope::getPhpVersion() (#6551), thanks @staabm!
  • Resolve PHP version checks in remaining scope-aware extensions from Scope::getPhpVersion() and forbid injecting PhpVersion into them (#6563), #15287, thanks @staabm and @SanderMuller!
  • DeprecatedCastRule: Utilize Scope::getPhpVersion() (#6600), thanks @staabm!
  • Do not cast floats past the int range, or NAN, where PHP does not (#6541)
  • Ask isCallable() of callable-like arrays and strings only where the answer is consumed (#6559), #15292
  • Narrow the left side of ?? to null in a non-true context only when its other values cannot satisfy it (#6581)
  • Memoize hasInstanceProperty() into its own cache (#6597)
  • Keep an empty array next to an oversized array in a union (#6609)
  • Do not report a private method overriding a private trait method as unused (#6191), #12201, thanks @Jean-Beru!
  • Keep the narrowed bound of a template type that TemplateTypeHelper::resolveTemplateTypes() maps to itself (#6613), #15321, thanks @staabm!
  • Do not remember a void equality assertion statement as true when its arguments contain an impure call (#6625), #15328
  • Compare the element type of a variadic by-ref parameter against its out type (#6227), #15066, thanks @SanderMuller!
  • Keep unresolved template arguments of different sites apart, solve covariant ones like Hack (#6650), #15331

Performance 🏎️

  • Turbo now shadows majority of the analyser engine (#6499, #6503, #6506, #6508, #6509, #6511, #6521, #6523, #6530, #6532, #6533, #6535)
  • Resolve constant offsets on constant arrays through the key index (#6442)
  • Speed up enum-case removal, finite type counting, large unions and loop widening of shapes (#6443)
  • Memoize PhpMethodReflection::getName() and return the right operand on a TypeCombinatorCache memo hit (#6489)
  • Harden Turbo traversal, arena, and iterable parity (#6538)
  • Build smaller turbo binaries (#6552)
  • Pass immutable array arguments non-refcounted through zv::Args (#6561), thanks @zonuexe!
  • Cheaper file cache, type memo bookkeeping and expression-key lookups (#6568)
  • Share one NamespaceUses between the name scopes of a file (#6583), #15304
  • Share one N...
Read more

2.2.17

Choose a tag to compare

@phpstan-bot phpstan-bot released this 04 Oct 19:49
Immutable release. Only release title and notes can be modified.
e676a49

This is the last release in 2.2.x series. Look forward to PHPStan 2.3.0 which is going to be released next week with the following highlights:

  • Massive leap in performance (again!)
  • Generics improvements (bidirectional type narrowing which closes #6732 and dozens of duplicate issues)
  • Unused variables detection

Here's what new and changed in PHPStan 2.2.17:

Improvements 🔧

  • Compile PHP 8.6 turbo binaries against 8.6.0RC2 (#6599)
  • Build Linux ZTS turbo binaries for PHP 8.6+ (#6657)
  • Point method visibility errors at the method, not its first attribute (#6630), #14398, thanks @Cayan!

Bugfixes 🐛

  • Cache parsed ASTs behind the path routing, one cache per parser (#6569), #15231, thanks @SanderMuller!
  • Keep optional groups optional within a matched regex alternation branch (#6596), #15297
  • Do not track string keys of an unpacked non-literal expression in DuplicateKeysInLiteralArraysRule (#6635), #15295, thanks @VincentLanglet and @staabm!

Performance 🏎️

Function signature fixes 🤖

  • Fix the return type of SessionHandler::read() to string|false (#6639), thanks @Firehed!

Internals 🔍

  • Load dead-code-detector in self-analysis only on PHP 8.2 and later (#6591), thanks @SanderMuller!
  • Mutation testing: diff against a configured branch, cover only the changed files (#6664)

2.2.16

Choose a tag to compare

@phpstan-bot phpstan-bot released this 25 Sep 09:33
Immutable release. Only release title and notes can be modified.
46a6d90

Bugfixes 🐛

  • Treat possible Error throws as an effect of an expression statement again (phpstan/phpstan-src@6a09253)
  • Keep a by-ref writeback's native type only when the written-back type fits it (#6564), thanks @SanderMuller!
  • Report worker peak memory when the result cache is used (#6576), thanks @alfredbez!
  • Compare ternary arm values, not their truthiness, in exact narrowing contexts (#6580), #15307, #15226
  • Keep the normalized branches of a traversed ConditionalType normalized, Narrow the parameter for nested conditions on the same parameter (#6586), #15310, #15296

Internals 🔍

  • Fix flaky tests (#6361)

2.2.15

Choose a tag to compare

@phpstan-bot phpstan-bot released this 23 Sep 12:38
Immutable release. Only release title and notes can be modified.
b158556

Bleeding edge 🔪

  • Report non-stringable names in variable variables, dynamic method calls and dynamic static property/method access (#5871), #4710, thanks @VincentLanglet and @staabm!

If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:

includes:
	- vendor/phpstan/phpstan/conf/bleedingEdge.neon

Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more

Improvements 🔧

  • PHPStan supports running on PHP 8.6 runtime
    • php-8-stubs were updated with new and changed functions too
    • Full analyser support for new PHP 8.6 features is coming later this year
  • Remove the PHP version constraint from the #[\NoDiscard] attribute rules. (#6444), #14586, thanks @claudepache!
  • Support for different versions of native PHP extensions, for example ext-ds v1 vs. v2 (#6250), #14539, thanks @simPod!
    • only ext-ds and ext-couchbase are currently supported
    • PHPStan uses the extension version constraint from composer.json
  • Check for property hooks being pure/impure (#6246), thanks @AJenbo!
  • Add Error class to uncheckedExceptionClasses by default (phpstan/phpstan-src@2fd897a), #15271
  • Resolve conditional @throws types like ($x is 0 ? Exception : void) at call sites and throw points (#5874), #7906, #9497, thanks @VincentLanglet and @staabm!
  • Update nikic/PHP-Parser to 5.9.0 (#6498)
  • Detect FILTER_THROW_ON_FAILURE in filter_input(), filter_var_array() and filter_input_array() (#6514)
  • Report function calls with an argument count no variant accepts (#6531)

Bugfixes 🐛

  • Keep an optional path as written where a plain one would be (#6452), #15238, thanks @SanderMuller!
  • Wrap NameResolver errors into ParserErrorsException so they are attributed to the file they come from (#6455), #15252
  • Write the offset instead of intersecting with HasOffsetValueType when overwriting an ArrayDimFetch (#6456), #15246
  • Merge sub-expression throw points, impure points, hasYield and terminating flags instead of overwriting them (#6457), #15249
  • Derive the % result range from the divisor's magnitude and the dividend's sign and bounds (#6458), #15243
  • ParametersAcceptorSelector: keep the acceptor-level variadic flag separate from the per-parameter one (#6460), #15251
  • Stop tracking the next implicit array key once it reaches PHP_INT_MAX (#6461), #15244
  • Do not use PHPDoc types as native types in foreach shape unrolling, list destructuring and by-ref writeback (#6463), #15250
  • Detect trait and parent class reference cycles instead of walking them forever (#6465), #8082
  • Pass the dim fetch paired with the offset to shouldKeepList() and guard the tracked-link setExistingOffsetValueType() shortcut (#6466), #15245, thanks @staabm!
  • Compare literal array offsets as the keys they become (#6466), #15245, thanks @staabm!
  • Detect overflowing << bounds, keep float for PHP_INT_MIN / -1, and bound % on non-integer operands (#6459), #15242
  • Track implicit indices past unpacked constant arrays and do not append past PHP_INT_MAX (#6464), #15247, #15248
  • Advance the implicit index by an unpacked item's integer keys in array literals (#6462), #15247
  • Mark throw points coming from a throw expression and keep them as an effect of an expression statement (#6471), #15258
  • Narrow conditional type branches through NarrowedSubjectType instead of by identity (#6480), #15268
  • Do not step past PHP_INT_MAX when listing an integer range's finite types (#6481)
  • Memoize the expression keys of global constant lookups (#6481)
  • Normalize array keys through toArrayKey() in array_fill_keys and array_combine return types (#6078), #14980, thanks @VincentLanglet and @staabm!
  • Invalidate maybe-impure function return values after impure method/static calls (#5667), #13416, #12734, thanks @VincentLanglet and @staabm!
  • Constant-fold explode() into a ConstantArrayType when separator, string and limit are all constant (#6123), #15013, thanks @VincentLanglet and @staabm!
  • Un-prefix Filter\ and PDO\ class name strings in the PHAR (#6512), #15007
  • Infer rand() with $min greater than $max as the swapped range (#6531)
  • Do not infer false for get_class() without arguments on PHP 8 (#6531)
  • Do not let placeholder methods of intersection members override declared methods, properties, constants (#6537)

Performance 🏎️

  • Resolve a node's file and package dependencies in one pass over unique reflections (#6475)
  • Answer per node class what resolveDependencies() can reach (#6478), thanks @SanderMuller!
  • Skip rewriting an unchanged result cache (#6432), thanks @zonuexe!
  • Do not call range() for ranges longer than ARRAY_COUNT_LIMIT (#6531)

Function signature fixes 🤖

  • Add ReflectionClassConstant constructor throw type extension (#6440)
  • Fix the type of the options of the RedisArray constructor (#6399), thanks @mlocati!
  • Add the PHP 8.5 trace key to error_get_last() (#6470), thanks @janedbal!
  • Describe Random\Randomizer array, bytes and integer methods with dedicated dynamic return type extensions (#6469), #15256, thanks @VincentLanglet and @staabm!
  • Correct GearmanClient unique parameters (#6241), thanks @donatj!
  • Allow FILTER_THROW_ON_FAILURE in $options of filter_var() and filter_input() (#6513), #15007
  • Because recent jetbrains/phpstorm-stubs update added @throws ...Error for a lot of core functions, we had to introduce a lot of throw type extensions to negate the effect on analysis. The analysis recognizes cases from the AST and types when the Error can never be thrown.
    • Add min() and max() throw type extension (#6516)
    • Add printf family throw type extension (#6517)
    • Add round() throw type extension (#6520)
    • Add str_split() throw type extension (#6522)
    • Add array_chunk() throw type extension (#6524)
    • Add get_class() throw type extension (#6525)
    • Add unserialize() throw type extension (#6528)
  • Accept all eight rounding modes of round() on PHP 8.4 (#6531)
  • DynamicFunctionReturnTypeExtensions for PostgreSQL (#6074), thanks @vrana!

Internals 🔍

  • Add setShouldNotImplyOppositeCase() on SpecifiedTypes to replace FAUX function call workarounds (#5769), #14705, thanks @VincentLanglet and @staabm!
  • Improve TypeCombinator::addNull (#6493), thanks @VincentLanglet!
    • Keep never in MutatingScope::intersectButNotNever() instead of widening it to null (#6507)
  • Do not create a throw point for void returned by dynamic throw type extensions (#6515)
  • Replace PrintfHe...
Read more

2.2.14

Choose a tag to compare

@phpstan-bot phpstan-bot released this 12 Sep 21:41
Immutable release. Only release title and notes can be modified.
9c672e7

Improvements 🔧

  • Apply finally scope changes to try-catch exit points and check by-ref return types after finally (#6393), #13338
  • Fix PHP 8.6 deprecation in hoa/consistency (#6405), thanks @SanderMuller!

Bugfixes 🐛

  • Compare conditional expressions in MutatingScope::equals() (#6344), #15157, thanks @janedbal!
  • Fix containsNull() for union with null&T of mixed (#6390), thanks @vojtech-dobes!
  • Do not resolve include paths through a stream wrapper that is not registered (#6397), #15192
  • Do not treat mixed type arguments as compatible both ways when both generic types are parameterized (#6398), #15198
  • Fix union of template array-key with false losing the template (#6376), #13374, #13192, #10871, #8268, #7423, #7279, #7049, thanks @calebdw!
  • Fix false positive comparing identical generic types below level 8 (#6392), #13876, #12984, #12008, #11041, #10698, #9377, #9096, thanks @calebdw!
  • pcntl_exec() is not supported by blackfire (#6409), thanks @staabm!
  • UsedNamesRule: reset imported names at every namespace declaration instead of keying them by namespace name (#6413), #15215
  • Derive per-arm conditional expressions from overlapping ternary arm types (#6381), #7905
  • Record needle-implies-true conditional expression for in_array() assignments (#6381), #9752
  • Propagate conditional expressions through derived assignments (#6381), #13054
  • Do not report ?? null / ??= null as unnecessary when evaluating the right side has side effects (#6418), #15134, thanks @VincentLanglet and @staabm!

Performance 🏎️

  • Reduce repeated work when matching ignored errors (#6374), thanks @zonuexe!
  • Do not look up class reflection for properties without hooks (#6396)
  • Share the directory walk between the analyse and the scan file finder (#6396)
  • Read the exported PHPDoc scope off the AST instead of through FileTypeMapper (#6396)
  • Memoize ClassReflection::getName() (#6406)
  • Inline single-return getters when building the PHAR (#6406, #6412)
  • Remove a union of values from a set in one pass (#6427)
  • Key types by their value where describe() was standing in for it (#6427)
  • Answer reflection cache misses without a failing include() (#6430)

Function signature fixes 🤖

  • Locale::getPrimaryLanguage() can return empty string (#6400), thanks @BenMorel!

Internals 🔍

  • Fix PHPUnit warning (#6375), thanks @staabm!
  • Trust PHPStan's own types when running from a source checkout too (#6406)
  • Build the macOS turbo extension for arm64 only (#6407)

2.2.13

Choose a tag to compare

@phpstan-bot phpstan-bot released this 03 Sep 20:40
Immutable release. Only release title and notes can be modified.
9ba9ac7

Result cache finally becomes usable for monorepo setups. It knows exactly what needs to be reanalysed when PHP files included via "type": "path" Composer dependencies are edited and also when files in scanFiles/scanDirectories are edited. 🔍✏️

Many result cache bugs were squashed 🐛 and the serialization format changed to a much more efficient one. 🏎️

Bleeding edge 🔪

  • Level 5: Report in-place sort calls that cannot change the array (#6296), #15126

If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:

includes:
	- vendor/phpstan/phpstan/conf/bleedingEdge.neon

Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more

Improvements 🔧

  • Interpret array shape keys as @template types when a template of that name is in scope (#6322), #15145
    • Allows types like array{TKey: string} with @template TKey above

Bugfixes 🐛

  • Do not bind a template type to an argument absorbed by another union member (#6341), #8441
  • Normalize the result cache meta before comparing it with the restored one (#6346), #15125, #15152
  • Let OpenSslCipherMethodsProvider contribute its own result cache meta (#6338), thanks @SanderMuller!
  • Resolve template defaults referencing other templates in composite types (#6329), thanks @calebdw!
  • Rename the result cache into place instead of writing it over the old one (#6349, #6353), thanks @SanderMuller!
  • Do not locate symbols declared by the symfony/polyfill-* packages bundled with PHPStan itself (#6351), #15150
  • Stop interning TypeCombinator results in the turbo extension (#6355), #15151
  • Cover a file newly appearing in a scanDirectories directory (#6352), #15149
  • Fixed various bugs where the result cache could become stale (#6357)
  • Fix result cache invalidation with @var referenced classes (#6343), thanks @Mika-!
  • Re-analyse the files with errors when a Composer package changes (#6362), #15164
  • Do not let the exactness of new Foo() reach an inferred template argument (#6363), #15166
  • Invalidate the result cache when any extension file changes (#6368)

Performance 🏎️

  • PHPStan always runs with OPCache (#6324, #6325)
  • Strip run-time type checks from PHPStan's own code with a turbo optimizer pass (phpstan/phpstan-src@3788169)
  • Store the result cache in a framed serialize() format instead of a var_export'd PHP file (#5982), thanks @SanderMuller!
  • Edited PHP files from scanFiles and scanDirectories now properly invalidate files dependent on them in the result cache #6352
    • Previously they invalidated the whole result cache and full analysis was necessary, this is no longer the case
  • Result cache now notices edited PHP files in Composer dependencies added via "repositories" with "type": "path" (#6356)
    • Previously the result cache didn't notice this edit so it became stale and you had to run clear-result-cache to get fresh results
  • HashFunctionsReturnTypeExtension: init hash-algorithm list lazily (#6345), thanks @staabm!
  • Keep the result cache when the turbo extension is switched on or off (#6335), thanks @SanderMuller!
  • Track scanned files as file dependencies instead of invalidating the whole result cache (#6352), #15149
  • Do not invalidate the result cache when tmpDir changes (#6359), thanks @SanderMuller!

Function signature fixes 🤖

  • Give password_get_info() the array shape it always returns (#6299), thanks @SanderMuller!

Internals 🔍

  • Cover constant fetch, enum case, static call, instanceof and typehints in checkImportedClassNameCase tests (#6347), thanks @janedbal!

2.2.12

Choose a tag to compare

@phpstan-bot phpstan-bot released this 31 Aug 19:12
Immutable release. Only release title and notes can be modified.
174b0d8

Improvements 🔧

  • Cap the detected CPU core count by the cgroup CPU quota (#6317)
  • Implement worker auto-scaler (#6256), thanks @AJenbo!

Bugfixes 🐛

  • Look up the stub PHPDoc of a class only when it is read (#6316), #15120
  • Export PHPDoc name scopes without resolving @template bounds (#6316)
  • Read property virtuality off the native reflection when exporting nodes (#6316)
  • Keep the turbo code that runs before the Composer autoloader polyfill-free (#6319), #15137
  • End forked workers with _exit() instead of PHP's full teardown (#6320), #15138, #15142

Performance 🏎️

2.2.11

Choose a tag to compare

@phpstan-bot phpstan-bot released this 31 Aug 10:34
Immutable release. Only release title and notes can be modified.
0eb899d

Improvements 🔧

  • Add a result-cache-info command reporting how the next analyse would use the result cache (#6312), #15135

Bugfixes 🐛

2.2.10

Choose a tag to compare

@phpstan-bot phpstan-bot released this 30 Aug 12:47
Immutable release. Only release title and notes can be modified.
36d1509

This release brings improved performance and reduced memory consumption, mainly thanks to:

  • Forking parallel workers where available:
    • Instead of spawning processes with proc_open(), they are forked with pcntl_fork(), saving time to bootstrap PHPStan
    • This requires PHPStan Turbo extension (already present if you install PHPStan with Composer) and non-Windows OS
  • Deduped objects held in memory by BetterReflection
  • Turbo extension-accelerated directories symbols scanning which allowed us to remove caching of this data and locking in worker processes

Feel free to comment how PHPStan 2.2.9 vs. 2.2.10 perform on your project! 🚀

Bleeding edge 🔪

  • Check written case of single-part class names imported with use statements (#6271), #12827, thanks @janedbal!

If you want to see the shape of things to come and adopt bleeding edge features early, you can include this config file in your project's phpstan.neon:

includes:
	- vendor/phpstan/phpstan/conf/bleedingEdge.neon

Of course, there are no backwards compatibility guarantees when you include this file. The behaviour and reported errors can change in minor versions with this file included. Learn more

Improvements 🔧

  • Notify in CI when a full analysis ran without a pre-existing result cache for more than 60 seconds (#5954), #14881, thanks @staabm!
  • Emit node callbacks after the node's results are stored and drop FNSR introduced in 2.1.34 (#6248)
  • Report peak memory per process instead of a summed total (#6297)

Bugfixes 🐛

  • Return the operand from union() for equal array operands, not just identical ones (#6257), thanks @AJenbo!
  • Preserve surviving offsets when popping or shifting a list (#6274)
  • Account for deduplicated trait errors per using-class context (#6280), #14932
  • Revert "Consult bootstrap-registered custom autoloaders only after the static source locators (#6069)" (#6292), #15102
  • Run StubFilesExtensions only after bootstrapFiles have been executed (#6284), #15120

Performance 🏎️

  • Use LruCache for the other three least-recently-used caches (#6240), thanks @SanderMuller!
  • Replay the recorded fixpoint pass instead of repeating the final loop walk (#6249)
  • Fork parallel workers (instead of spawning) whenever the turbo extension is active (#6260)
  • Intern TypeCombinator results in turbo (#6261), thanks @AJenbo!
  • Bound ObjectType's static caches with a shared LRU over description keys (#6289), #15119
  • Update BetterReflection
  • Scan directories natively, and drop the cache and lock behind it (#6304)

Function signature fixes 🤖

  • Clean out redundant stub overwrites (#6243), thanks @AJenbo!
  • Make SensitiveParameterValue generic (#6272), thanks @JanTvrdik!
  • Fix simplexml_import_dom() parameter type on PHP 8.4 (#6290), thanks @janedbal!

Internals 🔍

  • Fix incorrect casing (#6244), thanks @AJenbo!
  • Introduce StmtHandler (#6247)
  • Feed engine gatherers from NodeScopeResolver frames instead of wrapping node callbacks (#6258)
  • Replay scope-deriving mutators in NodeCallbackScope answers (#6259)
  • Ignore the turbo version constant in the typos check (#6270), thanks @SanderMuller!
  • Migrate a deprecated isSubclassOf call (#6268), thanks @AJenbo!
  • Guard against null in getNameScope (#6267), thanks @AJenbo!
  • Remove unused variables (#6266), thanks @AJenbo!
  • CS for build/PHPStan/ (phpstan/phpstan-src@bbd64b4)
  • Run bootstrapFiles per forked worker instead of inheriting the parent's (#6264)
  • phar.yml - get quicker to commit step (phpstan/phpstan-src@ccbde4b)
  • Price enum case values through InitializerExprTypeResolver in EnumSanityRule (#6275)
  • Extract function-call scope effects into FuncCallScopeEffectsHelper (#6279)
  • Cover the facade-alias shape with an e2e project (#6265), thanks @SanderMuller!
  • Use early exit when collecting the registered class loaders (#6282), thanks @SanderMuller!
  • Cover the loader shapes the reverted autoloader attempts broke (#6293), thanks @SanderMuller!