| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| phpstan.phar | 2026-09-23 | 30.0 MB | |
| phpstan.phar.asc | 2026-09-23 | 833 Bytes | |
| 2.2.15 source code.tar.gz | 2026-09-23 | 12.3 MB | |
| 2.2.15 source code.zip | 2026-09-23 | 12.3 MB | |
| README.md | 2026-09-23 | 10.4 kB | |
| Totals: 5 Items | 54.6 MB | 6 | |
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-dsv1 vs. v2 (#6250), [#14539], thanks @simPod! - only
ext-dsandext-couchbaseare 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
uncheckedExceptionClassesby default (https://github.com/phpstan/phpstan-src/commit/2fd897a5a9d0a639ea74cd77c63ea8fe7d2c6e92), [#15271] - Resolve conditional
@throwstypes 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_FAILUREinfilter_input(),filter_var_array()andfilter_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
NameResolvererrors intoParserErrorsExceptionso they are attributed to the file they come from (#6455), [#15252] - Write the offset instead of intersecting with
HasOffsetValueTypewhen overwriting anArrayDimFetch(#6456), [#15246] - Merge sub-expression throw points, impure points,
hasYieldand 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
foreachshape 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-linksetExistingOffsetValueType()shortcut (#6466), [#15245], thanks @staabm! - Compare literal array offsets as the keys they become (#6466), [#15245], thanks @staabm!
- Detect overflowing
<<bounds, keepfloatforPHP_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
throwexpression 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()inarray_fill_keysandarray_combinereturn 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 aConstantArrayTypewhen separator, string and limit are all constant (#6123), [#15013], thanks @VincentLanglet and @staabm! - Un-prefix
Filter\andPDO\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
tracekey toerror_get_last()(#6470), thanks @janedbal! - Describe
Random\Randomizerarray, bytes and integer methods with dedicated dynamic return type extensions (#6469), [#15256], thanks @VincentLanglet and @staabm! - Correct GearmanClient
uniqueparameters (#6241), thanks @donatj! - Allow
FILTER_THROW_ON_FAILUREin$optionsoffilter_var()andfilter_input()(#6513), [#15007] - Because recent
jetbrains/phpstorm-stubsupdate added@throws ...Errorfor 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()onSpecifiedTypesto replace FAUX function call workarounds (#5769), [#14705], thanks @VincentLanglet and @staabm! - Improve TypeCombinator::addNull (#6493), thanks @VincentLanglet!
- Keep
neverinMutatingScope::intersectButNotNever()instead of widening it tonull(#6507) - Do not create a throw point for void returned by dynamic throw type extensions (#6515)
- Replace PrintfHelper with PrintfFormatParser (#6517)
- RequiredPhpVersionCommentTest cover
PHPStan/Build/data(#6534), thanks @staabm! - Stop building Linux ZTS turbo binaries (https://github.com/phpstan/phpstan-src/commit/a62e61a23b5855a6cdfde1126ddf0ed8946270ac)