Releases: phpstan/phpstan
0.9
This is a big one, 3½ months in the making. It packs so many new and useful features that this release deserves its own article with a little bit more space for explaining them 😊
PHPStan 0.9: A Huge Leap Forward - Medium.com
This release is sponsored by Roave:
Roave is a full-service web development firm, offering services such as consulting, training, software development, and more. Roave employs some of the most recognized and accomplished experts in the industry to ensure that organizations have access to the talent they need, when they need it.
I'm really lucky that I'm able to work on something I really love and that I can justify spending time on open-source instead of traditional paid work. And it's thanks to sponsors like Roave and also my patrons on Patreon.
Did you know that I offer issuing invoices for sponsorships of releases and for contributions either on Patreon or via PayPal? Contact me for details.
Here's a comprehensive list of all changes in PHPStan 0.9:
Major new features:
- Intersection types - #410, thanks @JanTvrdik!
- Intersection types are explained in-depth in this article on Medium.com.
- This feature helps PHPStan understand your code much better, and opens door to new areas like proper support of PHPUnit's mock objects.
- Improved support of union types
- Full support of PHP 7.2
- Next-gen phpDoc parser - #606, thanks @JanTvrdik!
- Support intersection types (
Connection&MockInterface
) - Support complex array types (
(string|int)[]
) - Support specifying array/iterable key types (
array<KeyType, ValueType>
,iterable<KeyType, ValueType>
) - Support any combination of all of the above using parentheses (
((Connection & MockInterface) | iterable<array<string | int>>)[]
) - Rule for checking invalid phpDoc syntax (level 2)
- Rule for checking incompatible types in phpDocs when compared to native ones (level 2)
- Support intersection types (
- New 1st party package with extra-strict rules for strongly-typed codebases: phpstan/phpstan-strict-rules
- PHAR (distributed in phpstan/phpstan-shim package) can be installed alongside extensions! (phpstan/phpstan-shim#2)
- Checking for various dead conditions
- Check correct case of referenced class names
- Although class names are case-insensitive, it's dangerous to reference them with an incorrect case because of autoloading on case-sensitive filesystems.
- Places in code that cause autoloading are checked on level 0, other places like
instanceof
and phpDocs on level 2
- Check arguments passed to foreach, only iterables are supported - level 3 (c391153)
Enhancements:
- Differentiate between undefined and might-be-undefined variables (5aa10a6)
- Specify known variable type when isset() is used instead of
mixed
(4c51312) - Use specific union type of union exception types in catch block instead of using
mixed
(ba190f0) - Always check nullables in StrictComparisonOfDifferentTypesRule (9d03413)
- Add support for number type (fef68c1) - #469, thanks @PurpleBooth!
- Simplify and improve ImpossibleInstanceOfRule (0c4e802) - #491, thanks @JanTvrdik!
- Function is_numeric leads to string|int|float type (c8807bc) - #364, #369, thanks @pepakriz!
- Check existence of all referenced classes when accessing a property (d56453f)
- Check existence of all referenced classes when calling a method (e99eadc)
- Scope - get type of constants accessed on parent (63f3d37)
- Better message when accessing constant on an unknown class (b22a6fc)
- AccessStaticPropertiesRule - check properties accessed on expressions (344f4b2)
- AccessStaticPropertiesRule - check whether the type supports properties (7a14b5e)
- Allow overriding native methods and properties with
@method
and@property
annotations (77a92fc, a7421ce) - #76, #244, #414, #431 - Support Symfony 4.x (c30fdd2) - #547
- Combine types in for/foreach/while/do-while loops with assignments from previous iteration (dc592c4, fa989c1, 4fcd11c) - #77, #176
- Fixed type of variable after complex while and foreach loops (613ddaa)
- Implement DynamicFunctionReturnTypeExtension interface (00ffe78) - #476, thanks @pepakriz!
- Narrowing type of an array with
instanceof
in array_filter function (808ead8) - #482, #561, thanks @JanTvrdik! - It's possible to register a rule for the
Trait_
root node (e6b037c) - #565 - Process rules registered to
ElseIf_
andCase_
nodes (6d5b613) - Support
global
keyword (b42c749) - #580 - Introducing ContainerFactory that can be used in 3rd party integration tests (4ff66ee)
- Moved
AbstractRuleTest
to src/ and renamed toPHPStan\Testing\RuleTestCase
to be reused in other 1st and 3rd party repositories (fddde6d) --debug
option for finding out on which file PHPStan crashes; rethrow internal errors (999d2c5)- Lazy creation of class properties and methods - prevents autoloading of untouched properties types (8055761, 3e0c8ba) - #576
- Check scope visibility of constructors when instantiating an object (2e96c3e)
- Check scope visibility when calling private constructor (d7c08e5)
- Check what else is wrong with static/instance method call even if it cannot be called because of scope visibility (77c8dd8, 6dbee10)
- Allow setting unlimited memory (95dea67) - #607, thanks @AJenbo!
- Rule can now be registered for a node interface (
PHPStan\Rules\Rule::getNodeType()
can return an interface name) (b738f1b) - thanks @JanTvrdik! - Support for
property_exists()
(85c1735) - #611 - Detect BrokerAwareClassReflectionExtension for more kinds of extensions (aa83bab)
- Deduce key types of literal arrays (199c5be)
- Allow overriding BrokerFactory in the configuration (8aad71a) - #615
- Internal errors - request to post the stack trace as a GitHub issue (444f4aa)
- Internal errors - stop after 50 occurences (8a3ea10)
BC breaks:
- If the variable has absolutely no chance of existing in the current scope, it's reported on level 0 instead of level 1. (5aa10a6)
- Drop support for Symfony 2.x (b57c6bf) and require at least 3.2 (f334167) - #547
- If you have version conflicts because of these constraints, please use
phpstan/phpstan-shim
package
- If you have version conflicts because of these constraints, please use
- Specific kinds of errors that originate from a wrong configuration can no longer be ignored - use
excludes_analyse
instead (05172a8) polluteScopeWithLoopInitialAssignments
is now on by default - it matches PHP behaviour. Initial assignments of variables in for loop and while loop condition can be used after the loop (2c659f8). - #339- Invalid forms of
@var
phpDoc tags are no longer supported/** @var $int int */
(Type must come first)- To convert the non-standard
@var
PHPDoc tag to the standard one, you can use "Replace in Path" in PhpStorm. Select the "Regexp" option and replace `(/**\s*+@var\s++)($[\w\d]++)\s++(...
- To convert the non-standard
0.8.5
0.8.4
This release contains several enhancements that sprouted from the work on 0.9 but can be released separately now. This is probably the last 0.8.x release before the more substantial 0.9 gets out. You can look forward to a lot of good stuff 😊 (check out dev-master for a sneak peek, but some things are broken right now)
Enhancements:
0.8.3
0.8.2
Improved compatibility when installed with Composer and --no-plugins
.
0.8.1
PHPStan accepts one-time donations through PayPal!
Besides PayPal, there's Patreon where you can support PHPStan with recurring monthly donations.
Enhancements:
- CLI outputs correct version number for all installation methods (#433, #160) - thanks @Jean85!
- Exclude analysed files earlier - this might result in a lower and more correct reported number of analysed files (#438) - thanks @kukulich!
- Support
if (is_int($foo) === true)
#399 - thanks @JanTvrdik - Highest level has
max
alias (runanalyse -l max
) #430 - [Rules & extensions developers-only] Allow determination of whether MixedType was explicit or default #423 - thanks @stefan-squareweave!
Bugfixes:
- Fallback to union in case where intersection is required (restores behaviour from 0.7) (#418, #417) - thanks @JanTvrdik!
- Various fixes for iterables (#443, #402)
- Fixed appending value to null (#403, #404) - thanks @JanTvrdik!
- Fixed
setproctitle()
#411 - Skip empty parts of phpDoc typehint 6e3dfcc
0.8
PHPStan is on Patreon! You can show your support by backing PHPStan on Patreon. Choose your reward from different tiers and be a part of PHPStan's sustainable future development. I will deeply appreciate it. Thanks!
PHPStan now has an on-line playground over at phpstan.org! Thanks to @JanTvrdik, you can try out the static analyser right in your browser!
Major new features:
- Parsing read-only/write-only properties with
@property-read
/@property-write
annotations. #285 (thanks @stekycz!) - Checking writing to read-only properties and reading from write-only properties (level 0 for accesses on
$this
and level 2 for the rest). This is useful in combo with@property-read|write
annotations and with custom class reflection extensions. - Reading and checking correctness of passed parameters to methods from
@method
annotations including variadic methods. #285 (thanks @stekycz!) - Check for duplicate keys in literal arrays (level 0)
- Checks for invalid key types in literal arrays, in
list()
and short array destructuring syntax, in writing to and reading from arrays (level 3) - Handle fatal errors when autoloading unknown classes/interfaces/traits #255 (thanks @Majkl578) This lowers the risk of a fatal error during analysis because of an unknown class.
Enhancements:
- For level 7 (checking possible nullables), PHPStan now considers check for truthy value as a confirmation of not-null value (
if ($possibleNullable)
) #278 #296 #291 - Added Checkstyle error formatter #271
- Getting annotation methods and properties also from interfaces #292
- Static calls on arbitrary expressions (not just on class names) are checked on level 2 and higher
- Separate setting to check arguments passed by reference on level 5. Use
checkArgumentsPassedByReference: true
in your config file if you're on a lower level and want to check this. - Read methods and properties from annotations also from traits
- Checking that constructors do not return anything (returned value is silently thrown away)
- Checking accessing properties on possible null values (level 7)
- Types assigned to properties are checked also for assign operations like
.=
- Simpler and faster caching without dependency on
nette/caching
#396 (thanks @kukulich!) - Parsing type of variable from
@var
annotation with type only #395 (thanks @stekycz!) TypeCombinator::combine
accepts multiple types as variadic argument
BC breaks:
- Removed support for PHP-Parser 2.x. #293 Use
phpstan/phpstan-shim
in case of conflicting dependencies. - Moved properties-related rules to
PHPStan\Rules\Properties
namespace. Rename the rules in case you're using completely custom ruleset (no predefined level). - Added isReadable/isWritable on PropertyReflection
Bugfixes:
- Fixed mysqli::query parameters count #280
- Fixed argument count for DateTimeZone::getTransitions() #297
- DateInterval has microseconds since PHP 7.1 #311
- Fixed looking for inheritDoc when the phpDoc is in an interface
- Fixed \Locale::getDisplayLanguage() and locale_get_display_language() 2nd parameter optionality #312
- Added first parameter to DOMDocument::saveHTML() #279
- Find dynamic return type extensions in case the scope class name case does not match the reality
- Fixed deleting non-existent memory limit file when the rule level is not passed as CLI option while it should
- Changed all use of "catched" to "caught" #341
- PHPStan does not crash on PHP 7.2 (full support coming soon)
- Type specifier: fixed handling of nested logical operators #338
- CallToCountOnlyWithArrayOrCountableRule: fixed union handling
- Add better description to "call on nullable" error #282
- Fixed internal error when analysing short array destructuring syntax from PHP 7.1 with missing item #368
- RequireParentConstructCallRule fix: supressed constructor calls are now detected correctly #312
- Fixed resolving variable and expression types from branches. This fixed a lot of issues in conditional code. #277 #299 #355
- Fixed overriding specified variable type in foreach and catch
- Fixed availability of variables in finally block defined in try and catch blocks with early termination
- Fixed undefined variables because of other assign operations #322
- Correct type for string with multiple parts in doublequotes #376
- Fixed imagewebp reflection - added 3rd optional parameter #389
- Fix "incorrect case" error when using trait aliases #391
0.7
This is a huge release that was in the works for the last 2.5 months! I'd like to do smaller and more frequent releases from now on so that users don't have to wait that long for improvements and bugfixes to arrive to a stable version.
PHPStan is on Patreon! You can show your support by backing PHPStan on Patreon. Choose your reward from different tiers and be a part of PHPStan's sustainable future development. I will deeply appreciate it. Thanks!
Major new features:
- Big changes around union types and nullables:
- Nullables are now part of UnionType and are now handled equally to other common types. This leads to better detection of nullables when they are passed incorrectly.
- Functions/methods can check for returned nullables better than before
- Eliminating types from union in if/elseif/else branches and ternary operator
- Introduced three new levels!
- Level 5: Check passed function/methods argument types (only numbers of arguments are checked on lower levels)
- Also: check whether the argument passed to
count()
function is an array or a Countable, otherwise PHP always returns 1 - Also: check whether an argument for parameter passed by reference is a variable (otherwise PHP emits a notice)
- Also: check whether the argument passed to
- Level 6: Check compliance with union types
- Level 7: Check nullables more strictly
- Also: check whether a method is called on a possible nullable #194
- Level 5: Check passed function/methods argument types (only numbers of arguments are checked on lower levels)
- Support parsing and using
@method
annotations - thanks @petaak and @rquadling! #99 - PHPStan can now be installed and used via a PHAR archive (instructions are in README). This solves the problem of conflicting versions of dependencies used by PHPStan and by the analyzed projects. Also, the relevant package phpstan/phpstan-shim allows installing the selected PHAR archive via Composer without the risk of conflicting dependencies, so it can be used in any project. You can also download the final PHAR below these release notes. Big thanks to @fprochazka!
- Support for custom error formatters #185
- Unified working with classes and anonymous classes. This will probably fix some bugs and inconsistencies related to anonymous classes as a nice side effect.
- Check for undefined constants (level 1). You must define your constants in an autoloaded file or otherwise PHPStan cannot see them.
- Nice analysis speedup #256 - thanks @lookyman!
- Default temp dir for caching changed to the result of
sys_get_temp_dir()
- thanks @fprochazka! #250 - Temp dir is now configurable - thanks @fprochazka! #250
Enhancements
- Check accessed static properties even outside of class scope
- Check called static method even outside of class scope
- Better messages for inaccessible properties/methods/constants from current scope
- ClassConstantRule - checking wrong usage of static and parent
- Instantiation - check self and static outside of class scope
- Instantiation - support parent
- Improve error message in StrictComparisonOfDifferentTypesRule (#136 - thanks @mzk!)
- Added support for
scalar
pseudotype - Report inner named functions #165
- Ignore nonexistent fastcgi_ functions #226
- universalObjectCratesClasses - allow class autoloader to be defined later than this extension is initialized #252
- Support FloatType alias double in phpDocs #214
- Define types of magic constants like
__DIR__
or__CLASS__
- Combining float and int results in float|int, not just float
- Result type of min and max functions is mostly known #113
- Type override applies only to the nearest assign of the same expression
- Arrays created from array_ functions aren't checked for appended item types
- Specified boolean type as result of
<=
,<
,>
,>=
- Custom class reflection extensions are prioritized before annotation extensions
- Combine types with foreach even if we don't know that it ever loops
- Get correct value type when accessing a constant.
BC breaks
- Removed option
defineVariablesWithoutDefaultBranch
because it was a maintenance burden and didn't make much sense
BC breaks (for rules & extension developers)
Scope::getClass()
(string|null) was replaced withScope::getClassReflection()
(ClassReflection, always returns an object - check forisInClass()
beforehand), also includes anonymous class reflection- Removed
Type::isNullable()
and all thebool $nullable
parameters from Type implementations constructors. UsePHPStan\Type\TypeCombinator::addNull()
to create a nullable union type.
Bugfixes
- Solve if-else-if-else problem (#118, #209, #243)
- Fix ReflectionClass::newInstance variadic argument #178
- Do not report empty return statement on functions/methods with yield #166
- Added missing properties for classes from PHP DOM extension reflection #148
- Fixed anonymous class with inherited constructor #142
- Fixed analyzing traits on Windows
- Function parameters with non-null default value were considered nullable
- Properties and static properties are not typed to null when they are checked against null
- Do not override type with is_array to mixed[] if argument is already an array
- Fix printf parameters rule (several times - #217, #211)
- Do not check printf and similar calls with unpacked arguments #253
- Fixed defect in session_start parameter #241
- Do not require call to abstract constructor #205
- Support $argc and $argv variables when defined #232
- Follow symlinks in analysed directories #218
- RequireParentConstructCallRule - do not analyze constructors in traits #112
- FileExcluder should match case-insensitively on Windows #261
- Fixed VariableCloningRule for union types
- Fixed mixed return types processing issue #105
- Do not create an array variable when appending values to an ArrayAccess (#268)
- Variadic parameters also accept Traversables and iterables (#272)
- Respect variable type after assign operation like *= or /= (#114)
finally
is always executed, variables defined in there are available below try-catch-finally (#140)
0.6.4
Enhancements:
- Added support for custom php file extensions (#128 - thanks @mfettig!)
- Support Symfony 2.7 to be compatible with more dependencies, most notable Laravel 5.1 LTS (#151 - thanks @nCrazed!)
- Support experimental Nette 3.0 alpha
Bugfixes:
- Do not report unknown variable in
isset()
(#122) - Variables used in
compact()
call are considered as used when checking constructor parameters and used closure variables (#121 - thanks @cinamo!) - Add XMLReader properties missing from native PHP reflection (#139 - thanks @pavelkovar!)
- CallableType accepts any object with
__invoke
method (#147 - thanks @PavelJurasek!) - Fix
imagepng()
definition (#127 - thanks @finwe!) - Fixed resolving defined variables in branches for short array destructuring syntax from PHP 7.1 (#124)
Version 0.7 is in active development, PHPStan is going to experience a big leap once again!
0.6.3
Dynamic return type extensions are discovered also via an interface (implemented especially for PHPStan Doctrine extension)