Phan is a static analyzer for PHP. Phan prefers to avoid false-positives and attempts to prove incorrectness rather than correctness.
@throws
types from parent methods if enable_phpdoc_types
is true (which it is by default). (#4757)PhanTypeMismatchUnpackKeyArraySpread
when minimum_target_php_version
is '8.1'
or newer. (#4788)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+.\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.
EmptyStatementListPlugin
issue messages.exif_read_data()
(#4759)allow_missing_properties
setting aware of AllowDynamicProperties
attribute for PHP 8.2AST_ARROW_FUNC
in php 8.2 match older php versions.readonly
classes in the polyfill/fallback parser.__halt_compiler()
in the polyfill/fallback parser.A|(B&C)
(https://wiki.php.net/rfc/dnf_types). (#4699)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.PhanTypeModifyImmutableObjectProperty
for PHP 8.1 readonly
properties when modified anywhere outside of the
declaring class's scope. (#4710)array_filter
$callback
to be null (#4715)tool/analyze_phpt
to analyze phpt files. See https://www.phpinternalsbook.com/tests/phpt_file_structure.html
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.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)ast\Node
when running Phan in php 5.2.0 with the polyfill instead of the native php-ast version.PhanGenericConstructorTypes
warning to the class inheriting a constructor if needed (#4675)"${}"
string interpolation (#4692)$var
in in_array($var, $array)
instead of just the type of the array elements (#4630)phan --init
, allow inferring php 8.1 as the target php version in the generated config file. (#4655)Fix AST download link for PHP 8.0+ for Windows (#4645)
Fix dead code detection for PHP 8.0 non-capturing catch statements. (#4633) This should still analyze the catch body even if there is no caught exception variable.
Ignore phpdoc comment tags that don't start at the start of a line of the doc comment (* @sometag
) or aren't an inline tag (* something {@sometag}
). (#4640)
See https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/internal.html and https://docs.phpdoc.org/2.9/guides/docblocks.html
E.g. * This is not @abstract.
is no longer treated as an abstract method.
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.PhanDeprecatedPartiallySupportedCallableAlternateScope
for uses of callables such as [new SubClass(), 'Base::method']
specifying an alternate scope.PhanPluginUnknownClosureParamType
and PhanPluginUnknownFunctionParamType
.#[AllowDynamicProperties]
.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)
EmptyStatementListPlugin
(#4555)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)count($arr) > 0
and count($arr) >= 1
that the array is non-empty. (#4551)/
) on windows (#4149)$arr[true]
) (#4573)--processes N
CLI flag before checking if phan should restart without grpc
(#4608)if ($x === []) {...} else {...}
, if (count($x) > 0) {...} else {...}
, etc.PhanTypeNonVarPassByRef
to critical. It throws an Error in php 8.0+. (#3830)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)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
PhanPluginMoreSpecificActualReturnType
for phpdoc array shape return type and returned generic array. (#4531)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)
get_headers
(#3273)AddNeverReturnTypePlugin`` which will suggest adding a phpdoc return type of
@return never`. (#4468)numeric-string
in all phpdocPhanTypeMismatchPropertyDefaultReal
warning for literal integer and float
typed property. (#4507)PhanImpossibleTypeComparison
about string subtypes not casting to other string subtypes (#4514)BlockExitStatusChecker
to indicate that a function will exit or infinitely loop (STATUS_NORETURN
) (#4468)--help
, --version
, and crash reports (#4487)
The environment variable PHAN_SUPPRESS_PHP_UPGRADE_NOTICE=1
can be set to disable this notice.(...)
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.