Phan Versions Save

Phan is a static analyzer for PHP. Phan prefers to avoid false-positives and attempts to prove incorrectness rather than correctness.

5.4.3

4 months ago

New Features(Analysis):

  • Automatically inherit @throws types from parent methods if enable_phpdoc_types is true (which it is by default). (#4757)

Miscellaneous:

  • Fix ldap function signatures
  • Fix a couple of array spread crash bugs
  • Extend supported dependency versions of symfony/console to also allow 7.x (#4822)
  • Require php-ast 1.1.1 or newer in PHP 8.3+ if php-ast is installed.

Bug fixes:

  • Fix interfaces can extend BackedEnum and UnitEnum (#4782)
  • Fix ini_set() signature to take any scalar since PHP 8.1 (#4806)
  • Fix RedisCluster setOption/getOption signatures (#4790)
  • Don't emit PhanTypeMismatchUnpackKeyArraySpread when minimum_target_php_version is '8.1' or newer. (#4788)
  • Fix a couple of array spread crash bugs (#4780)
  • Fix crash if match is used inside for-loop (#4767)
  • Fix DateTime::getTimestamp return type (#4731)
  • Avoid deprecation warning for ASSERT constants in php 8.3+ (#4808)
  • Use ini_set() instead of assert_options() when Phan's assertion options match PHP's assert ini setting defaults to keep those values and avoid deprecation warnings in php 8.3+.
  • Fix crash in AST fallback parser when parsing invalid ArgumentExpression in php 8.0+
  • Fix false positive warnings and skipping internal constants declared by PECLs prefixed with \x00 (APCu, immutable_cache)

This release fixes errors and deprecations seen running Phan with PHP 8.3, but it does not support analyzing most new syntax/features/changes deprecations of PHP 8.3 itself.

5.4.2

1 year ago

Miscellaneous:

  • Fix wording in EmptyStatementListPlugin issue messages.
  • Add a few more functions where the return value should be used.
  • Fix signature of exif_read_data() (#4759)
  • Make allow_missing_properties setting aware of AllowDynamicProperties attribute for PHP 8.2

Maintenance:

  • Require php-ast 1.1.0 or newer in PHP 8.2+ if php-ast is installed. This release of php-ast makes the parsing of AST_ARROW_FUNC in php 8.2 match older php versions.
  • Support parsing of PHP 8.2 syntax such as disjunctive normal form types and readonly classes in the polyfill/fallback parser.
  • Fix bugs parsing __halt_compiler() in the polyfill/fallback parser.

5.4.1

1 year ago

New Features(Analysis):

  • Support parsing php 8.2's disjunctive normal form types (e.g. A|(B&C) (https://wiki.php.net/rfc/dnf_types). (#4699)
  • Support php 8.2 class constants on trait RFC. (#4687) Emit PhanCompatibleTraitConstant when using constants on traits with a minimum_target_php_version below '8.2' Emit PhanAccessClassConstantOfTraitDirectly when directly referencing the class constant on the trait declaration.
  • Emit PhanTypeModifyImmutableObjectProperty for PHP 8.1 readonly properties when modified anywhere outside of the declaring class's scope. (#4710)

Miscellaneous:

  • Allow array_filter $callback to be null (#4715)

5.4.0

1 year ago

New Features(CLI, Configs):

New Features(Analysis):

  • Support php 8.2's true type (https://wiki.php.net/rfc/true-type). Emit PhanCompatTrueType when true is used when minimum_target_php_version is less than 8.2.
  • Emit PhanCompatStandaloneType instead of PhanInvalidNode for uses of null/false as real standalone types to support php 8.2 https://wiki.php.net/rfc/null-false-standalone-types (Not emitted when minimum_target_php_version is 8.2 or higher)
  • Improve support for php 8.2 readonly classes and php 8.1 readonly properties

Bug fixes:

  • Fix php 8.2.0-dev deprecation notice for ast\Node when running Phan in php 5.2.0 with the polyfill instead of the native php-ast version.
  • Fix DuplicateArrayKeyPlugin "Implicit conversion from float ... to int" warning causing crash in php 8.1 (#4666)
  • Fix slow memory leak of reference cycles in the language server - enable garbage collection for the Phan daemon/language server consistently. (#4665) (This fix is only enabled in php 7.3+ when using pcntl, the pcntl fallback already re-enabled garbage collection. php 7.3 improved the garbage collection efficiency for large collections of objects.)
  • Move PhanGenericConstructorTypes warning to the class inheriting a constructor if needed (#4675)
  • Fix crash when combining types for null and an array with PHP_INT_MAX as a key (#4688)
  • Fix incorrect type inference for arrays with keys that were invalid UTF-8 (#4688)
  • Fix error due to deprecation notice running Phan in php 8.2 due to use of "${}" string interpolation (#4692)

5.3.2

2 years ago

New Features(Analysis):

  • Use intersection type of original variable value and array elements when inferring type of $var in in_array($var, $array) instead of just the type of the array elements (#4630)
  • Treat type of concatenation of one or more non-real strings as a phpdoc(non-real) string with the real type string. (#4635)
  • In phan --init, allow inferring php 8.1 as the target php version in the generated config file. (#4655)

Maintenance:

  • Allow installing xdebug-handler version ^3.0 (#4639)
  • Allow installing symfony/console version ^6.0 (#4642)

Bug fixes:

5.3.1

2 years ago

New Features(Analysis):

  • Emit PhanDeprecatedPartiallySupportedCallable for functions that work with call_user_func($expr) but not $expr(). The literal strings 'self', 'parent', and 'static' in 'self::methodName' or ['self', 'methodName'] in callables were deprecated in PHP 8.2.
  • Emit PhanDeprecatedPartiallySupportedCallableAlternateScope for uses of callables such as [new SubClass(), 'Base::method'] specifying an alternate scope.
  • Make pass-by-ref vars result in a merged union type, not an overwritten one. (#4602)

Plugins:

  • Update format string message for PhanPluginUnknownClosureParamType and PhanPluginUnknownFunctionParamType.

Bug fixes:

  • Avoid crashing when running in PHP 8.2+ after php 8.2 deprecated dynamic(undeclared) properties on classes without #[AllowDynamicProperties].

5.3.0

2 years ago

New Features(Analysis):

  • Fix false positive PhanPossiblyUndeclaredVariable warning when a try block unconditionally returns/throws/exits (#4419)

  • Fix false positive warnings when analyzing enums, infer that automatically generated methods of enums exist. (#4313)

  • Properly resolve template type when getIterator returns an Iterator that includes a template. (#4556)

  • Fix false positives such as PhanTypeMismatchArgumentNullable analyzing recursive call with parameter set to literal, without real type information. (#4550) (e.g. function ($retry = true) { if ($retry) {/*...*/} some_call_using_retry($retry); })

  • Properly detect PhanUnusedVariable in try-catch where catch always rethrows. (#4567)

  • Make read-only/write-only property detection more accurate for assignment operations (e.g. +=, ??=) and increment/decrement operations. (#4570)

  • Improve estimates of array sizes when analyzing calls that unpack values, based on the inferred real type set. (#4577)

  • Infer that variadic parameters can have string keys (as of php 8.0) (#4579)

  • Emit PhanParamTooFewUnpack and PhanParamTooFewInternalUnpack to indicate when argument unpacking may provide too few arguments to the called function. (#4577)

  • Support the non-standard @no-named-arguments PHPDoc comment on function-likes. (#4580, #4152) Treat variadic parameters as list types when this annotation is used, warn about unpacking string arguments or explicitly passing named arguments to functions using this declaration.

  • Warn about argument unpacking that may pass strings to internal functions (e.g. var_dump(...['a' => 'unsupported'])) (#4579) New issue types: PhanSuspiciousNamedArgumentVariadicInternalUnpack

  • Support @phan-type AliasName=UnionType annotation in inline strings or element comments (#4562)

    These aliases will apply to remaining statements in the current top-level namespace blocks, similar to use statements, but can also be defined in methods and apply to subsequent methods.

    This can be of use in avoiding repetition of phpdoc for long type definitions.

    // Alternate inline string version to work around php-ast limitations
    '@phan-type UserData = array{name: string, id: int, createdAt: DateTime}';
    
    /**
     * @type-alias UserData = array{name: string, id: int, createdAt: DateTime}
     * (applies to phpdoc in this and all subsequent AST nodes in the namespace block)
     */
    class ExampleElementWithPHPDoc {
        /**
         * @param UserData[] $users
         * @return list<UserData>
         */
        public function filterUsers(array $values): array { /* ... */ }
    }
    
    // The UserData alias is still defined and can be used in other statements
    
    namespace XYZ;
    // The UserData alias is no longer defined in the new namespace block.
    
  • When analyzing calls that modify variables as pass by reference, merge old types with existing types to account for possibility of branches or early returns (#4602)

Plugins:

  • Warn about non-empty try statements that are unlikely to throw in EmptyStatementListPlugin (#4555)
  • Warn in AlwaysReturnPlugin about functions/methods with no return type that have at least one return statement with an expression, but may fall through to the end of the function body without an explicit return (#4587)

Bug fixes:

  • Fix off-by-one error when inferring from comparison conditions such as count($arr) > 0 and count($arr) >= 1 that the array is non-empty. (#4551)
  • Fix checking file path suppressed by baseline (with /) on windows (#4149)
  • Fix crash when inferring type of array access for scalar other than int/string (e.g. $arr[true]) (#4573)
  • Properly read --processes N CLI flag before checking if phan should restart without grpc (#4608)

Maintenance:

  • Account for a few PHP 8.0 signature changes for PDOStatement::fetchAll and Phar methods. (#4569)

5.2.1

2 years ago

New Features:

  • Improve analysis of conditions detecting the empty/non-empty array. (#4523) E.g. support if ($x === []) {...} else {...}, if (count($x) > 0) {...} else {...}, etc.
  • Raise severity of PhanTypeNonVarPassByRef to critical. It throws an Error in php 8.0+. (#3830)
  • Infer from conditions such as in_array($var, $array, true) that $array is a non-empty array and that $var is of a type found in the elements of $array. (#2511)

Plugins:

  • Emit a proper warning when InvokePHPNativeSyntaxCheckPlugin is passed a path to a php binary that is missing or invalid (or if the syntax check crashed). (#4116) Previously, Phan would crash with an error such as fwrite(): write of 8196 bytes failed with errno=32 Broken pipe
  • Fix false positive PhanPluginMoreSpecificActualReturnType for phpdoc array shape return type and returned generic array. (#4531)

Bug fixes:

  • Fix type inference logic that was looking for array specializations rather than array or any array subtype (#4512)

  • Fix false positive PhanUnreferencedClosure/PhanUnreferencedFunction seen when a closure/function name was passed to a function such as uasort that already had a plugin analyzing calls of the closure. (#4090, #4519)

  • Fix false positive/negative PhanTypeMissingReturn* instances. (#4537)

    The check was wrong and should have been checking for a statement list that throws/exits. Return statements can be omitted if a function unconditionally exits.

    Also, check for the real never return type when emitting issues

  • Fix false positive PhanPossiblyUndefinedGlobalVariable* instance when global $var is used within a conditional. (#4539)

  • Fix false positive PhanPluginRedundantAssignmentInLoop instance when a variable is modified in a catch statement with a break/continue. (#4542)

  • Fix some incorrect line numbers in some plugin issues.

  • Fix crash seen when parsing intersection types containing union types such as non-empty-array&array<'a'|'b'> (#4544)

Maintenance:

  • Fix old return type signature for get_headers (#3273)
  • Print instructions on how to upgrade php-ast to 1.0.11+ if an outdated version is installed. (#4532)

5.2.0

2 years ago

Plugins

  • Add AddNeverReturnTypePlugin`` which will suggest adding a phpdoc return type of @return never`. (#4468)

Bug fixes:

  • When using the polyfill parser, properly parse nullable class property declarations as nullable. (#4492)
  • Don't emit PhanIncompatibleRealPropertyType for private base property. (#4426)
  • Fix false positive where a method overriding an existing method could be treated as having overrides. (#4502)
  • Consistently support numeric-string in all phpdoc
  • Fix false positive PhanTypeMismatchPropertyDefaultReal warning for literal integer and float typed property. (#4507)
  • Fix false positive warnings such as PhanImpossibleTypeComparison about string subtypes not casting to other string subtypes (#4514)

Maintenance:

  • Change internal representation of FunctionSignatureMap delta files.
  • Add a new exit status bit flag to BlockExitStatusChecker to indicate that a function will exit or infinitely loop (STATUS_NORETURN) (#4468)
  • Internally represent the base function map using php 8.0 signatures instead of php 7.3 - applying deltas backwards has the same result (#4478)

4.1.0

2 years ago

Maintenance:

  • Recommend using Phan 5 when analyzing code (#4487)
  • Mention that Phan 5 has been released in --help, --version, and crash reports (#4487) The environment variable PHAN_SUPPRESS_PHP_UPGRADE_NOTICE=1 can be set to disable this notice.
  • Warn if attempting to execute Phan 4.x with PHP 8.1 (Phan 5 fully supports all PHP 8.1 features, notably intersection types)
  • Upgrade from tolerant-php-parser 0.0.23 to 0.1.1
  • Backport some changes from Phan 5 for php 8.1 first-class callable conversion (...) and avoid crashing when parsing intersection types. Note that Phan 5 must be used instead to actually support intersection types; intersection types are not part of Phan 4's type system.