Download Latest Version Phan 6.0.0 source code.tar.gz (2.1 MB)
Email in envelope

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

Home / 6.0.0
Name Modified Size InfoDownloads / 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)

Source: README.md, updated 2026-01-16