| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| Phan 6.0.0 source code.tar.gz | 2026-01-16 | 2.1 MB | |
| Phan 6.0.0 source code.zip | 2026-01-16 | 2.5 MB | |
| README.md | 2026-01-16 | 24.2 kB | |
| Totals: 3 Items | 4.7 MB | 6 | |
Phan NEWS
Jan 16 2026, Phan 6.0.0
Bug fixes:
- Fixed crash when analyzing implicit float-to-int conversion in modulo operator (#5392)
- Fixed PhanUnreferencedClosure being emitted too aggressively for closure function parameters (#5389)
- Fixed false positives for readonly properties in traits when targeting PHP < 8.2 (#5390)
- Fixed detection of property usages from trait methods (#5391)
- Fixed match expression type narrowing when multiple conditional expressions are used (#5398)
- Fixed PhanTypeMismatchArgumentSuperType false positives on closure parameters (#5402)
- Fixed array shape narrowing with count() - only narrow closed array shapes with optional keys (#5406)
- Improved distinction between list-like array shapes and general array shapes (#5407)
- Fixed "Possibly invalid offset" only appearing for some accesses in a foreach loop (#5409)
- Fixed IS_PROMOTED_PROPERTY flag detection for constructor property promotion (#5411, #5416)
- Fixed non-exhaustive match detection with literal bool edge cases (#5388)
Improvements:
- Performance optimizations for template type substitution and FQSEN caching (#5417, #5418)
- Early-exit checks in Method::cloneWithTemplateParameterTypeMap to avoid unnecessary cloning
- Optimized CallableParamPlugin for functions with no parameters
- Two-level cache for FullyQualifiedClassElement::make using object IDs
- Allow Symfony 8.0 compatibility (#5401)
- Fixed composer-patches package location for PHP 8.5 compatibility (#5387)
Nov 20 2025, Phan 6.0.0-beta
Breaking changes:
- Requires PHP 8.1+ to run and minimum target version is now PHP 8.1
- Requires php-ast 1.1.3+ for PHP 8.4+ analysis (AST version 110/120 support)
- The -i CLI option is now an alias of --incremental instead of --ignore-undeclared
- Renamed the PhanPluginCanUsePHP71Void issue to PhanPluginCanUseVoidReturnType
- Dropped the allow_method_param_type_widening config option (contravariance is now always allowed)
- Dropped the backward_compatibility_checks config option, along with its respective --backward-compatibility-checks and -b CLI flags
New features (Analysis):
- Large literal arrays are now summarized to representative samples during parsing, significantly reducing peak memory when analyzing massive datasets.
- Default limits can be tuned via the new config options ast_trim_max_elements_per_level (default 256) and ast_trim_max_total_elements (default 512).
- Union types are automatically clamped once they exceed max_union_type_set_size (default 1024), preventing runaway growth from deeply nested array merges while keeping type inference useful.
- These trim/clamp thresholds are also exposed as CLI flags (--ast-trim-max-elements-per-level, --ast-trim-max-total-elements, --max-union-type-set-size) for easy experimentation without editing config files.
- Detect implicit float-to-int conversion in modulo operator (deprecated in PHP 8.1)
- New issue type: PhanTypeInvalidModuloOperand
- Warns when float types are used with the modulo (%) operator
- Improved analysis of intersection types with unknown classes (#4431)
- When an intersection type includes both known and unknown classes, Phan now analyzes the known types
- Method calls and property access are checked against known classes in the intersection
- Enables type checking even when some dependencies are missing or stubs are incomplete
- Also improves analysis of catch blocks with mixed known/unknown exception types
- Full support for PHP 8.5 features:
- #[NoDiscard] attribute support with detection of ignored return values (PhanNoDiscardReturnValueIgnored)
- #[Override] attribute extended to properties (in addition to methods)
- Pipe operator (|>) with full type inference through piped call chains
- (void) cast support for suppressing NoDiscard warnings
- Updated function signatures for PHP 8.5 standard library changes
- Full support for PHP 8.4 property hooks
- Parse and validate property hook syntax (get/set hooks)
- Parameter type checking for set hook parameters
- Validation of hooks with default values (PhanPropertyHookWithDefaultValue)
- Validation of readonly properties with set hooks (PhanReadonlyPropertyHasSetHook)
- Return type compatibility validation (PhanPropertyHookIncompatibleReturnType)
- Parameter type compatibility validation (PhanPropertyHookIncompatibleParamType)
- Final hook override detection (PhanPropertyHookFinalOverride)
- Support for PHP 8.4 #[Deprecated] attribute
- Recognize #[Deprecated] attribute on functions, methods, and class constants
- Works alongside existing @deprecated PHPDoc comment support
- Emits PhanDeprecatedFunction and PhanDeprecatedClassConstant warnings when deprecated elements are used
- Support for new PHP 8.4 functions and methods
- DateTime::createFromTimestamp() / DateTimeImmutable::createFromTimestamp()
- DOMXPath::registerPHPFunctionNS()
- All new PHP 8.4 functions: array_find, array_find_key, array_any, array_all, mb_trim, mb_ltrim, mb_rtrim, mb_ucfirst, mb_lcfirst, and more
- Full support for "new without parentheses" syntax (e.g., new MyClass()->method())
- Type inference works correctly across method chains
- Property and array access supported
- Multiline doc comments for @param, @var, and @return
- Doc comment parsing now normalizes multi-line @param, @var, and @return
annotations before analysis, allowing nested array/generic syntax to be laid out
across several lines without being misinterpreted.
- Extended multiline support to Phan-specific annotations: @phan-param, @phan-var, @phan-return, @phan-real-return, @phan-property*, @phan-assert, @phan-type, @phan-implements, @phan-extends, @phan-inherits, @phan-use (#4252)
- PHPDocRedundantPlugin now flags redundant @var annotations on typed
properties, matching its existing coverage for functions and methods.
- PreferNamespaceUsePlugin now handles union types
- Improved generics support (#5182)
- Enhanced template type handling and generic type inference
- Better resolution of generic types in complex scenarios
- Full support for PHP 8.3 typed class constants (#5140, #5128)
- Inheritance checking and validation
- New issue types: PhanTypeMismatchDeclaredConstant, PhanTypeMismatchDeclaredConstantNever, PhanConstantTypeMismatchInheritance
- Proper type narrowing for class constants in conditions (#5127)
- Literal type exclusion in !in_array() checks (#5185)
- Type narrowing when checking values against literal arrays (up to 50 elements)
- Improves precision when checking against known sets of values
- Reference assignment literal type erasure (#5197, #4354)
- Variables involved in reference assignments ($var2 =& $var1) now have their literal types erased
- Prevents incorrect literal type tracking when variables are aliased
- Applies to both sides of reference assignment and persists across subsequent assignments
- Enhanced type inference improvements:
- array_filter() recognizes null-stripping callbacks and keeps element types non-null (#5100)
- array_chunk() return type inference based on preserve_keys parameter (#5165)
- constant() return type inference from Phan's constant table for non-dynamic constants (#5157)
- stdClass property inference from array shape casts (#5151)
- Better static return type resolution preserving intersection types and generics (#5126)
- Improved foreach iterator type inference honoring explicit iterator generics (#5108)
- Conditional type refinement after array field checks (#5179)
- Static properties in conditional expressions (#5194)
- Type conditions with intermediary variables (#5125)
- Enum property access in constant expressions (#5158): support for self::CASE->value
- New detection capabilities:
- UncoveredEnumCasesInMatchPlugin (#5164): Detects when match expressions with enum conditions don't cover all enum cases
- Duplicate static variable detection (#5176): New PhanDuplicateStaticVariable issue (fatal error in PHP 8.3+)
- Multiple readonly property assignment (#5175): New PhanAccessReadOnlyPropertyMultipleTimes issue
- Redundant boolean type combinations (#5174): Warns on redundant type combinations
- Trait constant compatibility (#5119): New PhanIncompatibleCompositionConstant for conflicting trait constants
- Interface traits and readonly classes (#5118): Warns when interfaces use traits or readonly classes use non-readonly trait properties
- Improved unused variable detection (#5093): Catches more cases with compound assignment operators (+=, -=, etc.)
- Redundant property comments (#5107): Warns on redundant @var docblocks on typed properties
New features (CLI):
- Git-style config discovery (#5092):
- Searches parent directories for .phan/config.php
- Filters output when running from subdirectories
- New --subdirectory-only flag for analyzing specific modules with better performance
- -n/--no-config-file implicitly limits analysis to just the files provided
on the command line (e.g. phan -n test1.php test2.php) avoiding analysis of
the rest of the project when you only want quick ad-hoc checks.
- Added support for incremental analysis, where only changed files and their dependents
will be analyzed on subsequent runs. Significantly speeds up re-analysis.
- Add the --incremental / -i option that enables incremental analysis.
- Add the --force-full-analysis flag to force a full re-analysis of all files, ignoring the incremental analysis manifest.
- Add the --no-incremental / -N option that disables incremental analysis (useful if it was enabled in config.php).
Performance improvements: - phan_helpers C extension integration (#5096): - Optional C extension for 2-3x faster AST hashing and type deduplication - Overall analysis speedup: 5-15% for large projects - Automatically detected and used when available - Internal PHP stub definitions are now cached between CodeBase instances, so repeated test runs and daemon/server reloads reuse the previously parsed classes/functions without reparsing dozens of stub files on every initialization. - Conditional visitor optimization (#5186): - Skip visitor creation for ~60-70% of if statements (those without else/elseif) - Reduces memory usage and improves analysis speed - Incremental analysis support (see CLI features above) - Subdirectory-only mode for faster focused analysis
New features (Tools):
- Add tool/add_suppressions.php to assist in adding @suppress or @phan-suppress annotations to files
- Useful for batch suppressing specific issue types across the codebase
- See tool/SuppressionsToolImplementation.md for technical details
Bug fixes:
Type Inference & Analysis:
- Fixed too strict type inference after !empty() condition on arrays (#5295)
- Fixed union types containing both known objects and mixed being checked too strictly (#5292)
- Fixed PhanAccessReadOnlyPropertyMultipleTimes failing to account for mutually exclusive branches (#5285)
- Fixed declare blocks causing Phan to lose track of declared variables (#5284)
- Fixed conditionals causing wrong type inference for static properties (#5283)
- Fixed too strict PhanTemplateTypeConstraintViolation when type can't be resolved (#5282)
- Fixed Phan using unrelated array elements when inferring types (#5281)
- Fixed array shape type inference for is_object and !is_array checks with mixed types (#5277)
- Fixed static property type narrowing with type-check functions like is_null() and !is_null() (#5277)
- Fixed type accumulation for interface-typed properties ensuring method calls are validated against interface contract (#5300)
- Fixed spurious PhanPossiblyUndeclaredVariable with function calls and following usage (#5269)
- Fixed PhanTypeMismatchGeneratorYieldKey false positive when yield has no key (#5258)
- Fixed PhanAccessOwnConstructor incorrectly warning on valid usage of self::__construct (#5257)
- Fixed unnecessary array key aliasing in type narrowing when assignment happens in foreach iteration (#5255)
- Fixed array unions containing mixed types being checked too strictly for array offsets (#5299)
- Fixed condition-based type narrowing using outdated context when variable is modified in conditionals (#5301)
- Fixed isset() and empty() warning on undefined properties (now only warns on direct access and unset) (#5273)
- Fixed property type narrowing scope leaking into unrelated code paths (#5249)
- Fixed ArrayAccess type checking not validating offsetGet signature (#5251)
- Fixed DNF type false positive when using null defaults (#5252)
- Fixed array_combine signature being too strict for null values (#5219)
- Improved type inference for get_class() to return more specific class-string types (#5274)
- Improved handling of getIterator() returning Iterator with explicit generics (#5108)
- Traits can now declare @require-extends / @require-implements (and their Psalm aliases) to ensure consuming classes satisfy those requirements
- Fixed PhanPossiblyInfiniteRecursionSameParams false positive for instance methods that guard recursion with property state (#5371)
- Fixed PhanTypeMismatchDeclaredConstant false positives for enum cases whose values are strings/ints (#5378)
- Improved parameter and property default type representation in error messages (#5271)
Tooling:
- Baselines generated with --save-baseline now store suppressions per symbol (class/method/function) instead of line numbers and normalize anonymous class/closure names, so suppressions remain stable when code moves or hashes change (#5381/#5383)
Plugins:
- Fixed UnusedSuppressionPlugin incorrectly flagging magic method suppressions in class doc comments as unused (#5304)
- Added missing ANSI color mappings for terminal output (#5294)
- Improved confusing PhanSuspiciousValueComparison message when all literal possibilities exhausted (#5276)
- Fixed issue message for PhanCommentAbstractOnInheritance (#5265)
Other Fixes:
- Fixed nested closure scope tracking bug (#5291)
- Fixed multiline PHPDoc comment parsing issues (#5293)
- Fixed private property static/non-static mismatch detection in traits (#5247)
- Fixed internal stubs not being included in releases (#5244)
- Fixed nullsafe property access: No more strict object checking false positives with ?-> (#5112)
- Fixed trait method multi-level inheritance: Track trait methods through multiple inheritance levels (#5120)
- Fixed DNS aliases: Corrected reversed DNS aliases (#5170)
- Fixed private final constructor: Don't warn on private final constructors (exempted in PHP 8.0+) (#5169)
- Fixed float-to-int in modulo: Detect implicit float-to-int conversion in % operator (#5189)
- Fixed sibling type compatibility: Assignment visitor type checking now works correctly (#5168)
- Fixed dynamic array offset constants: Skip premature constant resolution for define() (#5156)
- Fixed unary operator type aggregation: Corrected numeric fallback ordering bug (#5146)
- Fixed xml_parser_create signature: Corrected incorrect signature (#5139)
- Fixed crash with intersection types: No more EmptyFQSENException with --analyze-twice (#5086)
- Fixed class constant regression: Corrected typed constant false positives after #5128 (#5133)
- Fixed intersection types with unknown classes: Proper method resolution when intersection contains both known and unknown classes (#5190)
- Fixed template type compatibility: No more false positive PhanTypeMismatchDeclaredReturn with template types (#5181)
- Fixed readonly property access: No more false positives with isset() on readonly properties in @phan-side-effect-free classes (#5180)
- Fixed switch fall-through variable tracking: Variable definitions now flow correctly through fall-through cases (#5155)
- Fixed try/catch variable scope: Variable definitions in try blocks with finally clauses now track correctly (#5152, #5131)
- Fixed global variable type pollution in daemon mode: Incremental re-analysis no longer pollutes global variable types (#5183)
- Fixed ternary in function arguments: Proper type narrowing for conditional expressions in arguments (#5166)
- Fixed empty array vs non-empty union: Re-checks union arguments mixing empty and non-empty arrays (#5115)
- Fixed array map callback analysis: No more false positive PhanParamTooFewUnpack with array_map (#5114)
- Fixed static call on trait properties: No more false positives after instanceof checks (#5111)
- Fixed never return type inheritance: Proper detection of inherited never methods via parent::/static:: (#5109)
- Fixed nested array shape field refinement: Suppressed property mismatch warnings when refining nested fields (#5106)
- Fixed enums as class constants: Allow enum types as class constant values (#5103)
- Fixed SID constant handling: Special-case handling for dynamically defined SID constant (#5150)
- Fixed reference assignment literal type erasure: Variables involved in reference assignments now correctly erase literal types to prevent false positives (#5197)
PHPDoc & Attributes:
- Fixed @deprecated detection for callable parameters: Emit PhanDeprecatedFunction when deprecated functions are passed as callable string arguments (#4858)
- Fixed @phan-suppress on class constants: Suppression annotations are no longer ignored (#5188)
- Fixed @phan-mandatory-param inheritance: Inherit annotation from interface methods (#5116)
- Fixed @phan-pure inheritance: Exclude __call and __callStatic from automatic inheritance (#5124)
- Fixed internal method purity: ArrayObject->count() now inherits pure flag from Countable (#5122)
- Fixed PHPDoc type inheritance: Proper inheritance of parameter types from interfaces (#5117)
Plugin Fixes:
- Fixed MoreSpecificElementTypePlugin: No more false positives with array{}|non-empty-array<K,V> (#5187)
- Fixed UnknownElementTypePlugin: No more false positives on inherited methods (#5177)
- Fixed RedundantConditionVisitor: No more false positives with static property empty() checks (#5148)
- Fixed CompactPlugin: Added check for possibly undefined variables (#5167)
- Fixed PHPDocRedundantPlugin: Added auto-fixer for redundant property comments (#5178)
Loop & Control Flow:
- Fixed possibly infinite loop detection: No more false positives when loop condition uses array count (#5153)
- Fixed !isset() variable tracking: Possibly-undefined flag preservation now works correctly (#5172)
- Fixed redundant condition after empty(): Proper static property handling (#5148)
AST Compatibility:
- Fixed AST version 110/120 compatibility for PHP 8.4
- Updated TolerantASTConverter to support AST version 120
- Fixed AST structural changes: closure 'name' field removal, parameter 'hooks' field addition, property 'hooks' field addition
- Fixed clone being incorrectly treated as a function call in AST version 110+ (it's now AST_CALL instead of AST_CLONE)