Download Latest Version 2.2.14 source code.zip (12.1 MB)
Email in envelope

Get an email when there's a new version of PHPStan

Home / 2.2.13
Name Modified Size InfoDownloads / Week
Parent folder
phpstan.phar 2026-09-03 28.6 MB
phpstan.phar.asc 2026-09-03 833 Bytes
2.2.13 source code.tar.gz 2026-09-03 12.6 MB
2.2.13 source code.zip 2026-09-03 12.6 MB
README.md 2026-09-03 5.6 kB
Totals: 5 Items   53.8 MB 5

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 (https://github.com/phpstan/phpstan-src/commit/37881692f422987f44eb31024231571d3150ec83)
  • 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!
Source: README.md, updated 2026-09-03